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