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