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