00001
00006 #include "system.h"
00007
00008 #ifndef PATH_MAX
00009
00010 # define PATH_MAX 255
00011
00012 #endif
00013
00014 #include <rpmcli.h>
00015
00016 #include "rpmdb.h"
00017 #include "rpmfi.h"
00018
00019 #define _RPMGI_INTERNAL
00020 #include "rpmgi.h"
00021 #include "rpmts.h"
00022
00023 #include "manifest.h"
00024 #include "misc.h"
00025
00026 #include "debug.h"
00027
00028
00029
00032 static void printFileInfo(char * te, const char * name,
00033 unsigned int size, unsigned short mode,
00034 unsigned int mtime,
00035 unsigned short rdev, unsigned int nlink,
00036 const char * owner, const char * group,
00037 const char * linkto)
00038
00039 {
00040 char sizefield[15];
00041 char ownerfield[8+1], groupfield[8+1];
00042 char timefield[100];
00043 time_t when = mtime;
00044 struct tm * tm;
00045 static time_t now;
00046 static struct tm nowtm;
00047 const char * namefield = name;
00048 char * perms = rpmPermsString(mode);
00049
00050
00051 if (now == 0) {
00052 now = time(NULL);
00053 tm = localtime(&now);
00054
00055 if (tm) nowtm = *tm;
00056
00057 }
00058
00059 strncpy(ownerfield, owner, sizeof(ownerfield));
00060 ownerfield[sizeof(ownerfield)-1] = '\0';
00061
00062 strncpy(groupfield, group, sizeof(groupfield));
00063 groupfield[sizeof(groupfield)-1] = '\0';
00064
00065
00066 sprintf(sizefield, "%12u", size);
00067
00068
00069
00070 if (S_ISLNK(mode)) {
00071 char *nf = alloca(strlen(name) + sizeof(" -> ") + strlen(linkto));
00072 sprintf(nf, "%s -> %s", name, linkto);
00073 namefield = nf;
00074 } else if (S_ISCHR(mode)) {
00075 perms[0] = 'c';
00076 sprintf(sizefield, "%3u, %3u", ((unsigned)(rdev >> 8) & 0xff),
00077 ((unsigned)rdev & 0xff));
00078 } else if (S_ISBLK(mode)) {
00079 perms[0] = 'b';
00080 sprintf(sizefield, "%3u, %3u", ((unsigned)(rdev >> 8) & 0xff),
00081 ((unsigned)rdev & 0xff));
00082 }
00083
00084
00085 tm = localtime(&when);
00086 timefield[0] = '\0';
00087 if (tm != NULL)
00088 { const char *fmt;
00089 if (now > when + 6L * 30L * 24L * 60L * 60L ||
00090 now < when - 60L * 60L)
00091 {
00092
00093
00094
00095
00096
00097
00098
00099 fmt = "%b %e %Y";
00100 } else {
00101 fmt = "%b %e %H:%M";
00102 }
00103 (void)strftime(timefield, sizeof(timefield) - 1, fmt, tm);
00104 }
00105
00106 sprintf(te, "%s %4d %-8s%-8s %10s %s %s", perms,
00107 (int)nlink, ownerfield, groupfield, sizefield, timefield, namefield);
00108 perms = _free(perms);
00109 }
00110
00113 static inline const char * queryHeader(Header h, const char * qfmt)
00114
00115 {
00116 const char * errstr = "(unkown error)";
00117 const char * str;
00118
00119
00120 str = headerSprintf(h, qfmt, rpmTagTable, rpmHeaderFormats, &errstr);
00121
00122 if (str == NULL)
00123 rpmError(RPMERR_QFMT, _("incorrect format: %s\n"), errstr);
00124 return str;
00125 }
00126
00129 static void flushBuffer(char ** tp, char ** tep, int nonewline)
00130
00131 {
00132 char *t, *te;
00133
00134 t = *tp;
00135 te = *tep;
00136 if (te > t) {
00137 if (!nonewline) {
00138 *te++ = '\n';
00139 *te = '\0';
00140 }
00141 rpmMessage(RPMMESS_NORMAL, "%s", t);
00142 te = t;
00143 *t = '\0';
00144 }
00145 *tp = t;
00146 *tep = te;
00147 }
00148
00149 int showQueryPackage(QVA_t qva, rpmts ts, Header h)
00150 {
00151 int scareMem = 0;
00152 rpmfi fi = NULL;
00153 size_t tb = 2 * BUFSIZ;
00154 size_t sb;
00155 char * t, * te;
00156 char * prefix = NULL;
00157 int rc = 0;
00158 int i;
00159
00160 te = t = xmalloc(tb);
00161
00162 *te = '\0';
00163
00164
00165 if (qva->qva_queryFormat != NULL) {
00166 const char * str = queryHeader(h, qva->qva_queryFormat);
00167
00168 if (str) {
00169 size_t tx = (te - t);
00170
00171 sb = strlen(str);
00172 if (sb) {
00173 tb += sb;
00174 t = xrealloc(t, tb);
00175 te = t + tx;
00176 }
00177
00178
00179 te = stpcpy(te, str);
00180
00181
00182 str = _free(str);
00183 flushBuffer(&t, &te, 1);
00184 }
00185
00186 }
00187
00188 if (!(qva->qva_flags & QUERY_FOR_LIST))
00189 goto exit;
00190
00191 fi = rpmfiNew(ts, h, RPMTAG_BASENAMES, scareMem);
00192 if (rpmfiFC(fi) <= 0) {
00193
00194 te = stpcpy(te, _("(contains no files)"));
00195
00196 goto exit;
00197 }
00198
00199 fi = rpmfiInit(fi, 0);
00200 if (fi != NULL)
00201 while ((i = rpmfiNext(fi)) >= 0) {
00202 rpmfileAttrs fflags;
00203 unsigned short fmode;
00204 unsigned short frdev;
00205 unsigned int fmtime;
00206 rpmfileState fstate;
00207 size_t fsize;
00208 const char * fn;
00209 char fmd5[32+1];
00210 const char * fuser;
00211 const char * fgroup;
00212 const char * flink;
00213 int_32 fnlink;
00214
00215 fflags = rpmfiFFlags(fi);
00216 fmode = rpmfiFMode(fi);
00217 frdev = rpmfiFRdev(fi);
00218 fmtime = rpmfiFMtime(fi);
00219 fstate = rpmfiFState(fi);
00220 fsize = rpmfiFSize(fi);
00221 fn = rpmfiFN(fi);
00222
00223 { static char hex[] = "0123456789abcdef";
00224 const char * s = rpmfiMD5(fi);
00225 char * p = fmd5;
00226 int j;
00227 for (j = 0; j < 16; j++) {
00228 unsigned k = *s++;
00229 *p++ = hex[ (k >> 4) & 0xf ];
00230 *p++ = hex[ (k ) & 0xf ];
00231 }
00232 *p = '\0';
00233 }
00234
00235 fuser = rpmfiFUser(fi);
00236 fgroup = rpmfiFGroup(fi);
00237 flink = rpmfiFLink(fi);
00238 fnlink = rpmfiFNlink(fi);
00239
00240
00241 if ((qva->qva_flags & QUERY_FOR_DOCS) && !(fflags & RPMFILE_DOC))
00242 continue;
00243
00244
00245 if ((qva->qva_flags & QUERY_FOR_CONFIG) && !(fflags & RPMFILE_CONFIG))
00246 continue;
00247
00248
00249 if ((qva->qva_fflags & RPMFILE_GHOST) && (fflags & RPMFILE_GHOST))
00250 continue;
00251
00252
00253 sb = strlen(fn) + strlen(fmd5) + strlen(fuser) + strlen(fgroup) + strlen(flink);
00254 if ((sb + BUFSIZ) > tb) {
00255 size_t tx = (te - t);
00256 tb += sb + BUFSIZ;
00257 t = xrealloc(t, tb);
00258 te = t + tx;
00259 }
00260
00261
00262 if (!rpmIsVerbose() && prefix)
00263 te = stpcpy(te, prefix);
00264
00265 if (qva->qva_flags & QUERY_FOR_STATE) {
00266 switch (fstate) {
00267 case RPMFILE_STATE_NORMAL:
00268 te = stpcpy(te, _("normal "));
00269 break;
00270 case RPMFILE_STATE_REPLACED:
00271 te = stpcpy(te, _("replaced "));
00272 break;
00273 case RPMFILE_STATE_NOTINSTALLED:
00274 te = stpcpy(te, _("not installed "));
00275 break;
00276 case RPMFILE_STATE_NETSHARED:
00277 te = stpcpy(te, _("net shared "));
00278 break;
00279 case RPMFILE_STATE_WRONGCOLOR:
00280 te = stpcpy(te, _("wrong color "));
00281 break;
00282 case RPMFILE_STATE_MISSING:
00283 te = stpcpy(te, _("(no state) "));
00284 break;
00285 default:
00286 sprintf(te, _("(unknown %3d) "), fstate);
00287 te += strlen(te);
00288 break;
00289 }
00290 }
00291
00292
00293 if (qva->qva_flags & QUERY_FOR_DUMPFILES) {
00294 sprintf(te, "%s %d %d %s 0%o ", fn, (int)fsize, fmtime, fmd5, fmode);
00295 te += strlen(te);
00296
00297 if (fuser && fgroup) {
00298
00299 sprintf(te, "%s %s", fuser, fgroup);
00300
00301 te += strlen(te);
00302 } else {
00303 rpmError(RPMERR_INTERNAL,
00304 _("package has not file owner/group lists\n"));
00305 }
00306
00307 sprintf(te, " %s %s %u ",
00308 fflags & RPMFILE_CONFIG ? "1" : "0",
00309 fflags & RPMFILE_DOC ? "1" : "0",
00310 frdev);
00311 te += strlen(te);
00312
00313 sprintf(te, "%s", (flink && *flink ? flink : "X"));
00314 te += strlen(te);
00315 } else
00316 if (!rpmIsVerbose()) {
00317
00318 te = stpcpy(te, fn);
00319
00320 }
00321 else {
00322
00323
00324 if (S_ISDIR(fmode)) {
00325 fnlink++;
00326 fsize = 0;
00327 }
00328
00329 if (fuser && fgroup) {
00330
00331 printFileInfo(te, fn, fsize, fmode, fmtime, frdev, fnlink,
00332 fuser, fgroup, flink);
00333
00334 te += strlen(te);
00335 } else {
00336 rpmError(RPMERR_INTERNAL,
00337 _("package has neither file owner or id lists\n"));
00338 }
00339 }
00340 flushBuffer(&t, &te, 0);
00341 }
00342
00343 rc = 0;
00344
00345 exit:
00346 flushBuffer(&t, &te, 0);
00347 t = _free(t);
00348
00349 fi = rpmfiFree(fi);
00350 return rc;
00351 }
00352
00353 void rpmDisplayQueryTags(FILE * fp)
00354 {
00355 const struct headerTagTableEntry_s * t;
00356 int i;
00357 const struct headerSprintfExtension_s * ext = rpmHeaderFormats;
00358
00359 for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++)
00360 if (t->name) fprintf(fp, "%s\n", t->name + 7);
00361
00362 while (ext->name != NULL) {
00363 if (ext->type == HEADER_EXT_MORE) {
00364 ext = ext->u.more;
00365 continue;
00366 }
00367
00368 for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
00369 if (t->name == NULL)
00370 continue;
00371 if (!strcmp(t->name, ext->name))
00372 break;
00373 }
00374 if (i >= rpmTagTableSize && ext->type == HEADER_EXT_TAG)
00375 fprintf(fp, "%s\n", ext->name + 7);
00376 ext++;
00377 }
00378 }
00379
00380 static int rpmgiShowMatches(QVA_t qva, rpmts ts)
00381
00382
00383 {
00384 rpmgi gi = qva->qva_gi;
00385 int ec = 0;
00386
00387 while (rpmgiNext(gi) == RPMRC_OK) {
00388 Header h;
00389 int rc;
00390
00391 h = rpmgiHeader(gi);
00392 if (h == NULL)
00393 continue;
00394 if ((rc = qva->qva_showPackage(qva, ts, h)) != 0)
00395 ec = rc;
00396 if (qva->qva_source == RPMQV_DBOFFSET)
00397 break;
00398 }
00399 return ec;
00400 }
00401
00402 int rpmcliShowMatches(QVA_t qva, rpmts ts)
00403 {
00404 Header h;
00405 int ec = 0;
00406
00407 while ((h = rpmdbNextIterator(qva->qva_mi)) != NULL) {
00408 int rc;
00409 if ((rc = qva->qva_showPackage(qva, ts, h)) != 0)
00410 ec = rc;
00411 if (qva->qva_source == RPMQV_DBOFFSET)
00412 break;
00413 }
00414 qva->qva_mi = rpmdbFreeIterator(qva->qva_mi);
00415 return ec;
00416 }
00417
00423 static inline unsigned char nibble(char c)
00424
00425 {
00426 if (c >= '0' && c <= '9')
00427 return (c - '0');
00428 if (c >= 'A' && c <= 'F')
00429 return (c - 'A') + 10;
00430 if (c >= 'a' && c <= 'f')
00431 return (c - 'a') + 10;
00432 return 0;
00433 }
00434
00435
00436 int rpmQueryVerify(QVA_t qva, rpmts ts, const char * arg)
00437 {
00438 int res = 0;
00439 const char * s;
00440 int i;
00441 int provides_checked = 0;
00442
00443 (void) rpmdbCheckSignals();
00444
00445 if (qva->qva_showPackage == NULL)
00446 return 1;
00447
00448
00449 switch (qva->qva_source) {
00450 case RPMQV_RPM:
00451 res = rpmgiShowMatches(qva, ts);
00452 break;
00453
00454 case RPMQV_ALL:
00455 res = rpmgiShowMatches(qva, ts);
00456 break;
00457
00458 case RPMQV_HDLIST:
00459 res = rpmgiShowMatches(qva, ts);
00460 break;
00461
00462 case RPMQV_FTSWALK:
00463 res = rpmgiShowMatches(qva, ts);
00464 break;
00465
00466 case RPMQV_SPECFILE:
00467 res = ((qva->qva_specQuery != NULL)
00468 ? qva->qva_specQuery(ts, qva, arg) : 1);
00469 break;
00470
00471 case RPMQV_GROUP:
00472 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_GROUP, arg, 0);
00473 if (qva->qva_mi == NULL) {
00474 rpmError(RPMERR_QUERYINFO,
00475 _("group %s does not contain any packages\n"), arg);
00476 res = 1;
00477 } else
00478 res = rpmcliShowMatches(qva, ts);
00479 break;
00480
00481 case RPMQV_TRIGGEREDBY:
00482 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_TRIGGERNAME, arg, 0);
00483 if (qva->qva_mi == NULL) {
00484 rpmError(RPMERR_QUERYINFO, _("no package triggers %s\n"), arg);
00485 res = 1;
00486 } else
00487 res = rpmcliShowMatches(qva, ts);
00488 break;
00489
00490 case RPMQV_PKGID:
00491 { unsigned char MD5[16];
00492 unsigned char * t;
00493
00494 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00495 {};
00496 if (i != 32) {
00497 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "pkgid", arg);
00498 return 1;
00499 }
00500
00501 MD5[0] = '\0';
00502 for (i = 0, t = MD5, s = arg; i < 16; i++, t++, s += 2)
00503 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00504
00505 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_SIGMD5, MD5, sizeof(MD5));
00506 if (qva->qva_mi == NULL) {
00507 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00508 "pkgid", arg);
00509 res = 1;
00510 } else
00511 res = rpmcliShowMatches(qva, ts);
00512 } break;
00513
00514 case RPMQV_HDRID:
00515 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00516 {};
00517 if (i != 40) {
00518 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "hdrid", arg);
00519 return 1;
00520 }
00521
00522 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_SHA1HEADER, arg, 0);
00523 if (qva->qva_mi == NULL) {
00524 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00525 "hdrid", arg);
00526 res = 1;
00527 } else
00528 res = rpmcliShowMatches(qva, ts);
00529 break;
00530
00531 case RPMQV_FILEID:
00532 { unsigned char MD5[16];
00533 unsigned char * t;
00534
00535 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00536 {};
00537 if (i != 32) {
00538 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "fileid", arg);
00539 return 1;
00540 }
00541
00542 MD5[0] = '\0';
00543 for (i = 0, t = MD5, s = arg; i < 16; i++, t++, s += 2)
00544 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00545
00546 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_FILEMD5S, MD5, sizeof(MD5));
00547 if (qva->qva_mi == NULL) {
00548 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00549 "fileid", arg);
00550 res = 1;
00551 } else
00552 res = rpmcliShowMatches(qva, ts);
00553 } break;
00554
00555 case RPMQV_TID:
00556 { int mybase = 10;
00557 const char * myarg = arg;
00558 char * end = NULL;
00559 unsigned iid;
00560
00561
00562 if (*myarg == '0') {
00563 myarg++;
00564 mybase = 8;
00565 if (*myarg == 'x') {
00566 myarg++;
00567 mybase = 16;
00568 }
00569 }
00570 iid = strtoul(myarg, &end, mybase);
00571 if ((*end) || (end == arg) || (iid == ULONG_MAX)) {
00572 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "tid", arg);
00573 return 1;
00574 }
00575 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_INSTALLTID, &iid, sizeof(iid));
00576 if (qva->qva_mi == NULL) {
00577 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00578 "tid", arg);
00579 res = 1;
00580 } else
00581 res = rpmcliShowMatches(qva, ts);
00582 } break;
00583
00584 case RPMQV_WHATREQUIRES:
00585 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_REQUIRENAME, arg, 0);
00586 if (qva->qva_mi == NULL) {
00587 rpmError(RPMERR_QUERYINFO, _("no package requires %s\n"), arg);
00588 res = 1;
00589 } else
00590 res = rpmcliShowMatches(qva, ts);
00591 break;
00592
00593 case RPMQV_WHATPROVIDES:
00594 if (arg[0] != '/') {
00595 provides_checked = 1;
00596 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, arg, 0);
00597 if (qva->qva_mi == NULL) {
00598 rpmError(RPMERR_QUERYINFO, _("no package provides %s\n"), arg);
00599 res = 1;
00600 } else
00601 res = rpmcliShowMatches(qva, ts);
00602 break;
00603 }
00604
00605 case RPMQV_PATH:
00606 { char * fn;
00607 int myerrno = 0;
00608
00609 for (s = arg; *s != '\0'; s++)
00610 if (!(*s == '.' || *s == '/'))
00611 break;
00612
00613 if (*s == '\0') {
00614 char fnbuf[PATH_MAX];
00615 fn = realpath(arg, fnbuf);
00616 if (fn)
00617 fn = xstrdup(fn);
00618 else
00619 fn = xstrdup(arg);
00620 } else if (*arg != '/') {
00621 const char *curDir = currentDirectory();
00622 fn = (char *) rpmGetPath(curDir, "/", arg, NULL);
00623 curDir = _free(curDir);
00624 } else
00625 fn = xstrdup(arg);
00626 (void) rpmCleanPath(fn);
00627
00628 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, fn, 0);
00629 if (qva->qva_mi == NULL) {
00630 if (access(fn, F_OK) != 0)
00631 myerrno = errno;
00632 else if (!provides_checked)
00633 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, fn, 0);
00634 }
00635
00636 if (myerrno != 0) {
00637 rpmError(RPMERR_QUERY, _("file %s: %s\n"), fn, strerror(myerrno));
00638 res = 1;
00639 } else if (qva->qva_mi == NULL) {
00640 rpmError(RPMERR_QUERYINFO,
00641 _("file %s is not owned by any package\n"), fn);
00642 res = 1;
00643 } else
00644 res = rpmcliShowMatches(qva, ts);
00645
00646 fn = _free(fn);
00647 } break;
00648
00649 case RPMQV_DBOFFSET:
00650 { int mybase = 10;
00651 const char * myarg = arg;
00652 char * end = NULL;
00653 unsigned recOffset;
00654
00655
00656 if (*myarg == '0') {
00657 myarg++;
00658 mybase = 8;
00659 if (*myarg == 'x') {
00660 myarg++;
00661 mybase = 16;
00662 }
00663 }
00664 recOffset = strtoul(myarg, &end, mybase);
00665 if ((*end) || (end == arg) || (recOffset == ULONG_MAX)) {
00666 rpmError(RPMERR_QUERYINFO, _("invalid package number: %s\n"), arg);
00667 return 1;
00668 }
00669 rpmMessage(RPMMESS_DEBUG, _("package record number: %u\n"), recOffset);
00670
00671 qva->qva_mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &recOffset, sizeof(recOffset));
00672 if (qva->qva_mi == NULL) {
00673 rpmError(RPMERR_QUERYINFO,
00674 _("record %u could not be read\n"), recOffset);
00675 res = 1;
00676 } else
00677 res = rpmcliShowMatches(qva, ts);
00678 } break;
00679
00680 case RPMQV_PACKAGE:
00681 {
00682 int matches = 0;
00683 rpmdbMatchIterator mi;
00684 mi = rpmtsInitIterator(ts, RPMDBI_LABEL, arg, 0);
00685 while (rpmdbNextIterator(mi) != NULL) {
00686 matches++;
00687 }
00688 rpmdbFreeIterator(mi);
00689 if (! matches) {
00690 rpmError(RPMERR_QUERYINFO, _("package %s is not installed\n"), arg);
00691 res = 1;
00692 } else {
00693 qva->qva_mi = rpmtsInitIterator(ts, RPMDBI_LABEL, arg, 0);
00694 res = rpmcliShowMatches(qva, ts);
00695 }
00696 break;
00697 }
00698
00699 }
00700
00701
00702 return res;
00703 }
00704
00705
00706 int rpmcliArgIter(rpmts ts, QVA_t qva, ARGV_t argv)
00707 {
00708 rpmRC rpmrc = RPMRC_NOTFOUND;
00709 int ec = 0;
00710
00711 switch (qva->qva_source) {
00712 case RPMQV_ALL:
00713 qva->qva_gi = rpmgiNew(ts, RPMDBI_PACKAGES, NULL, 0);
00714 qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, RPMGI_NONE);
00715
00716 if (qva->qva_gi != NULL && (qva->qva_gi->flags & RPMGI_TSADD))
00717 while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
00718 {};
00719 if (rpmrc != RPMRC_NOTFOUND)
00720 return 1;
00721
00722
00723 ec = rpmQueryVerify(qva, ts, (const char *) argv);
00724
00725 rpmtsEmpty(ts);
00726 break;
00727 case RPMQV_RPM:
00728 qva->qva_gi = rpmgiNew(ts, RPMDBI_ARGLIST, NULL, 0);
00729 qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, giFlags);
00730
00731 if (qva->qva_gi != NULL && (qva->qva_gi->flags & RPMGI_TSADD))
00732 while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
00733 {};
00734 if (rpmrc != RPMRC_NOTFOUND)
00735 return 1;
00736
00737
00738 ec = rpmQueryVerify(qva, ts, NULL);
00739
00740 rpmtsEmpty(ts);
00741 break;
00742 case RPMQV_HDLIST:
00743 qva->qva_gi = rpmgiNew(ts, RPMDBI_HDLIST, NULL, 0);
00744 qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, giFlags);
00745
00746 if (qva->qva_gi != NULL && (qva->qva_gi->flags & RPMGI_TSADD))
00747 while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
00748 {};
00749 if (rpmrc != RPMRC_NOTFOUND)
00750 return 1;
00751
00752
00753 ec = rpmQueryVerify(qva, ts, NULL);
00754
00755 rpmtsEmpty(ts);
00756 break;
00757 case RPMQV_FTSWALK:
00758 if (ftsOpts == 0)
00759 ftsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT);
00760 qva->qva_gi = rpmgiNew(ts, RPMDBI_FTSWALK, NULL, 0);
00761 qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts, giFlags);
00762
00763 if (qva->qva_gi != NULL && (qva->qva_gi->flags & RPMGI_TSADD))
00764 while ((rpmrc = rpmgiNext(qva->qva_gi)) == RPMRC_OK)
00765 {};
00766 if (rpmrc != RPMRC_NOTFOUND)
00767 return 1;
00768
00769
00770 ec = rpmQueryVerify(qva, ts, NULL);
00771
00772 rpmtsEmpty(ts);
00773 break;
00774 default:
00775 qva->qva_gi = rpmgiNew(ts, RPMDBI_ARGLIST, NULL, 0);
00776 qva->qva_rc = rpmgiSetArgs(qva->qva_gi, argv, ftsOpts,
00777 (giFlags | (RPMGI_NOGLOB|RPMGI_NOHEADER)));
00778 while (rpmgiNext(qva->qva_gi) == RPMRC_OK) {
00779 ec += rpmQueryVerify(qva, ts, rpmgiHdrPath(qva->qva_gi));
00780 rpmtsEmpty(ts);
00781 }
00782 break;
00783 }
00784
00785 qva->qva_gi = rpmgiFree(qva->qva_gi);
00786
00787 return ec;
00788 }
00789
00790 int rpmcliQuery(rpmts ts, QVA_t qva, const char ** argv)
00791 {
00792 rpmVSFlags vsflags, ovsflags;
00793 int ec = 0;
00794
00795 if (qva->qva_showPackage == NULL)
00796 qva->qva_showPackage = showQueryPackage;
00797
00798
00799 if (!(qva->qva_flags & _QUERY_FOR_BITS) && qva->qva_queryFormat == NULL) {
00800 qva->qva_queryFormat = rpmExpand("%{?_query_all_fmt}\n", NULL);
00801 if (!(qva->qva_queryFormat != NULL && *qva->qva_queryFormat != '\0')) {
00802 qva->qva_queryFormat = _free(qva->qva_queryFormat);
00803 qva->qva_queryFormat = xstrdup("%{name}-%{version}-%{release}\n");
00804 }
00805 }
00806
00807 vsflags = rpmExpandNumeric("%{?_vsflags_query}");
00808 if (qva->qva_flags & VERIFY_DIGEST)
00809 vsflags |= _RPMVSF_NODIGESTS;
00810 if (qva->qva_flags & VERIFY_SIGNATURE)
00811 vsflags |= _RPMVSF_NOSIGNATURES;
00812 if (qva->qva_flags & VERIFY_HDRCHK)
00813 vsflags |= RPMVSF_NOHDRCHK;
00814
00815 ovsflags = rpmtsSetVSFlags(ts, vsflags);
00816 ec = rpmcliArgIter(ts, qva, argv);
00817 vsflags = rpmtsSetVSFlags(ts, ovsflags);
00818
00819 if (qva->qva_showPackage == showQueryPackage)
00820 qva->qva_showPackage = NULL;
00821
00822 return ec;
00823 }