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