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