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