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