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
00316 if (te > t) {
00317
00318 *te++ = '\n';
00319 *te = '\0';
00320 rpmMessage(RPMMESS_NORMAL, "%s", t);
00321 te = t;
00322 *t = '\0';
00323
00324 }
00325
00326 }
00327
00328 rc = 0;
00329
00330 exit:
00331 if (te > t) {
00332 if (!nonewline) {
00333
00334 *te++ = '\n';
00335 *te = '\0';
00336
00337 }
00338 rpmMessage(RPMMESS_NORMAL, "%s", t);
00339 }
00340 t = _free(t);
00341
00342 fi = rpmfiFree(fi);
00343 return rc;
00344 }
00345
00350 static void
00351 printNewSpecfile(Spec spec)
00352
00353
00354 {
00355 Header h;
00356 speclines sl = spec->sl;
00357 spectags st = spec->st;
00358 const char * msgstr = NULL;
00359 int i, j;
00360
00361 if (sl == NULL || st == NULL)
00362 return;
00363
00364
00365 for (i = 0; i < st->st_ntags; i++) {
00366 spectag t = st->st_t + i;
00367 const char * tn = tagName(t->t_tag);
00368 const char * errstr;
00369 char fmt[1024];
00370
00371 fmt[0] = '\0';
00372 if (t->t_msgid == NULL)
00373 h = spec->packages->header;
00374 else {
00375 Package pkg;
00376 char *fe;
00377
00378
00379 strcpy(fmt, t->t_msgid);
00380 for (fe = fmt; *fe && *fe != '('; fe++)
00381 {} ;
00382 if (*fe == '(') *fe = '\0';
00383
00384 h = NULL;
00385 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
00386 const char *pkgname;
00387 h = pkg->header;
00388 (void) headerNVR(h, &pkgname, NULL, NULL);
00389 if (!strcmp(pkgname, fmt))
00390 break;
00391 }
00392 if (pkg == NULL || h == NULL)
00393 h = spec->packages->header;
00394 }
00395
00396 if (h == NULL)
00397 continue;
00398
00399 fmt[0] = '\0';
00400
00401 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tn), "}");
00402
00403 msgstr = _free(msgstr);
00404
00405
00406 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00407 if (msgstr == NULL) {
00408 rpmError(RPMERR_QFMT, _("can't query %s: %s\n"), tn, errstr);
00409 return;
00410 }
00411
00412
00413 switch(t->t_tag) {
00414 case RPMTAG_SUMMARY:
00415 case RPMTAG_GROUP:
00416
00417 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
00418
00419 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG))
00420 continue;
00421 { char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr));
00422 (void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr);
00423 sl->sl_lines[t->t_startx] = buf;
00424 }
00425 break;
00426 case RPMTAG_DESCRIPTION:
00427 for (j = 1; j < t->t_nlines; j++) {
00428 if (*sl->sl_lines[t->t_startx + j] == '%')
00429 continue;
00430
00431 sl->sl_lines[t->t_startx + j] =
00432 _free(sl->sl_lines[t->t_startx + j]);
00433
00434 }
00435 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) {
00436 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
00437 continue;
00438 }
00439 sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr);
00440 if (t->t_nlines > 2)
00441 sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n");
00442 break;
00443 }
00444
00445 }
00446
00447 msgstr = _free(msgstr);
00448
00449
00450 for (i = 0; i < sl->sl_nlines; i++) {
00451 const char * s = sl->sl_lines[i];
00452 if (s == NULL)
00453 continue;
00454 printf("%s", s);
00455 if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n')
00456 printf("\n");
00457 }
00458
00459 }
00460
00461 void rpmDisplayQueryTags(FILE * fp)
00462 {
00463 const struct headerTagTableEntry_s * t;
00464 int i;
00465 const struct headerSprintfExtension_s * ext = rpmHeaderFormats;
00466
00467 for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++)
00468 if (t->name) fprintf(fp, "%s\n", t->name + 7);
00469
00470 while (ext->name != NULL) {
00471 if (ext->type == HEADER_EXT_MORE) {
00472 ext = ext->u.more;
00473 continue;
00474 }
00475
00476 for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
00477 if (t->name == NULL)
00478 continue;
00479 if (!strcmp(t->name, ext->name))
00480 break;
00481 }
00482 if (i >= rpmTagTableSize && ext->type == HEADER_EXT_TAG)
00483 fprintf(fp, "%s\n", ext->name + 7);
00484 ext++;
00485 }
00486 }
00487
00488 int rpmcliShowMatches(QVA_t qva, rpmts ts)
00489 {
00490 Header h;
00491 int ec = 0;
00492
00493 while ((h = rpmdbNextIterator(qva->qva_mi)) != NULL) {
00494 int rc;
00495 if ((rc = qva->qva_showPackage(qva, ts, h)) != 0)
00496 ec = rc;
00497 }
00498 qva->qva_mi = rpmdbFreeIterator(qva->qva_mi);
00499 return ec;
00500 }
00501
00507 static inline unsigned char nibble(char c)
00508
00509 {
00510 if (c >= '0' && c <= '9')
00511 return (c - '0');
00512 if (c >= 'A' && c <= 'F')
00513 return (c - 'A') + 10;
00514 if (c >= 'a' && c <= 'f')
00515 return (c - 'a') + 10;
00516 return 0;
00517 }
00518
00519
00523 int (*parseSpecVec) (Spec *specp, const char *specFile, const char *rootdir,
00524 const char *buildRoot, int recursing, const char *passPhrase,
00525 char *cookie, int anyarch, int force) = NULL;
00529 Spec (*freeSpecVec) (Spec spec) = NULL;
00530
00531
00532
00533 int rpmQueryVerify(QVA_t qva, rpmts ts, const char * arg)
00534 {
00535 const char ** av = NULL;
00536 int res = 0;
00537 Header h;
00538 int rc;
00539 int xx;
00540 const char * s;
00541 int i;
00542
00543 (void) rpmdbCheckSignals();
00544
00545 if (qva->qva_showPackage == NULL)
00546 return 1;
00547
00548
00549 switch (qva->qva_source) {
00550 case RPMQV_RPM:
00551 { int ac = 0;
00552 const char * fileURL = NULL;
00553 rpmRC rpmrc;
00554
00555 rc = rpmGlob(arg, &ac, &av);
00556 if (rc) return 1;
00557
00558 restart:
00559 for (i = 0; i < ac; i++) {
00560 FD_t fd;
00561
00562 fileURL = _free(fileURL);
00563 fileURL = av[i];
00564 av[i] = NULL;
00565
00566
00567 fd = Fopen(fileURL, "r.ufdio");
00568 if (fd == NULL || Ferror(fd)) {
00569 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
00570 Fstrerror(fd));
00571 if (fd) (void) Fclose(fd);
00572 res = 1;
00573 break;
00574 }
00575
00576 rpmrc = rpmReadPackageFile(ts, fd, fileURL, &h);
00577
00578 (void) Fclose(fd);
00579
00580 res = 0;
00581 switch (rpmrc) {
00582 default:
00583 #ifdef DYING
00584 rpmError(RPMERR_QUERY, _("query of %s failed\n"), fileURL);
00585 #endif
00586 res = 1;
00587 break;
00588 case RPMRC_NOTTRUSTED:
00589 case RPMRC_NOKEY:
00590 case RPMRC_OK:
00591 if (h == NULL) {
00592 #ifdef DYING
00593 rpmError(RPMERR_QUERY,
00594 _("old format source packages cannot be queried\n"));
00595 #endif
00596 res = 1;
00597 break;
00598 }
00599
00600
00601 res = qva->qva_showPackage(qva, ts, h);
00602 h = headerFree(h);
00603 rpmtsEmpty(ts);
00604 continue;
00605 break;
00606 case RPMRC_NOTFOUND:
00607 res = 0;
00608 break;
00609 }
00610 if (res)
00611 break;
00612
00613
00614 fd = Fopen(fileURL, "r.fpio");
00615 if (fd == NULL || Ferror(fd)) {
00616 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
00617 Fstrerror(fd));
00618 if (fd) (void) Fclose(fd);
00619 res = 1;
00620 break;
00621 }
00622
00623
00624 res = rpmReadPackageManifest(fd, &ac, &av);
00625 if (res != RPMRC_OK) {
00626 rpmError(RPMERR_MANIFEST,
00627 _("%s: not an rpm package (or package manifest): %s\n"),
00628 fileURL, Fstrerror(fd));
00629 res = 1;
00630 }
00631 (void) Fclose(fd);
00632
00633
00634 if (res == 0)
00635 goto restart;
00636
00637 break;
00638 }
00639
00640 fileURL = _free(fileURL);
00641 if (av) {
00642 for (i = 0; i < ac; i++)
00643 av[i] = _free(av[i]);
00644 av = _free(av);
00645 }
00646 } break;
00647
00648 case RPMQV_SPECFILE:
00649 if (qva->qva_showPackage != showQueryPackage)
00650 return 1;
00651
00652
00653 if (parseSpecVec == NULL || freeSpecVec == NULL)
00654 return 1;
00655
00656 { Spec spec = NULL;
00657 Package pkg;
00658 char * buildRoot = NULL;
00659 int recursing = 0;
00660 char * passPhrase = "";
00661 char *cookie = NULL;
00662 int anyarch = 1;
00663 int force = 1;
00664
00665
00666 rc = parseSpecVec(&spec, arg, "/", buildRoot, recursing, passPhrase,
00667 cookie, anyarch, force);
00668
00669 if (rc || spec == NULL) {
00670 rpmError(RPMERR_QUERY,
00671 _("query of specfile %s failed, can't parse\n"), arg);
00672 spec = freeSpecVec(spec);
00673 res = 1;
00674 break;
00675 }
00676
00677 if (specedit) {
00678 printNewSpecfile(spec);
00679 spec = freeSpecVec(spec);
00680 res = 0;
00681 break;
00682 }
00683
00684 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next)
00685 xx = qva->qva_showPackage(qva, ts, pkg->header);
00686 spec = freeSpecVec(spec);
00687 } break;
00688
00689 case RPMQV_ALL:
00690 qva->qva_mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
00691 if (qva->qva_mi == NULL) {
00692 rpmError(RPMERR_QUERYINFO, _("no packages\n"));
00693 res = 1;
00694 } else {
00695 if (arg != NULL)
00696 for (av = (const char **) arg; *av; av++) {
00697 if (!rpmdbSetIteratorRE(qva->qva_mi, RPMTAG_NAME, RPMMIRE_DEFAULT, *av))
00698 continue;
00699 qva->qva_mi = rpmdbFreeIterator(qva->qva_mi);
00700 res = 1;
00701 break;
00702 }
00703 if (!res)
00704 res = rpmcliShowMatches(qva, ts);
00705 }
00706 break;
00707
00708 case RPMQV_GROUP:
00709 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_GROUP, arg, 0);
00710 if (qva->qva_mi == NULL) {
00711 rpmError(RPMERR_QUERYINFO,
00712 _("group %s does not contain any packages\n"), arg);
00713 res = 1;
00714 } else {
00715 res = rpmcliShowMatches(qva, ts);
00716 }
00717 break;
00718
00719 case RPMQV_TRIGGEREDBY:
00720 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_TRIGGERNAME, arg, 0);
00721 if (qva->qva_mi == NULL) {
00722 rpmError(RPMERR_QUERYINFO, _("no package triggers %s\n"), arg);
00723 res = 1;
00724 } else {
00725 res = rpmcliShowMatches(qva, ts);
00726 }
00727 break;
00728
00729 case RPMQV_PKGID:
00730 { unsigned char MD5[16];
00731 unsigned char * t;
00732
00733 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00734 {};
00735 if (i != 32) {
00736 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "pkgid", arg);
00737 return 1;
00738 }
00739
00740 MD5[0] = '\0';
00741 for (i = 0, t = MD5, s = arg; i < 16; i++, t++, s += 2)
00742 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00743
00744 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_SIGMD5, MD5, sizeof(MD5));
00745 if (qva->qva_mi == NULL) {
00746 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00747 "pkgid", arg);
00748 res = 1;
00749 } else {
00750 res = rpmcliShowMatches(qva, ts);
00751 }
00752 } break;
00753
00754 case RPMQV_HDRID:
00755 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00756 {};
00757 if (i != 40) {
00758 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "hdrid", arg);
00759 return 1;
00760 }
00761
00762 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_SHA1HEADER, arg, 0);
00763 if (qva->qva_mi == NULL) {
00764 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00765 "hdrid", arg);
00766 res = 1;
00767 } else {
00768 res = rpmcliShowMatches(qva, ts);
00769 }
00770 break;
00771
00772 case RPMQV_FILEID:
00773 { unsigned char MD5[16];
00774 unsigned char * t;
00775
00776 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00777 {};
00778 if (i != 32) {
00779 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "fileid", arg);
00780 return 1;
00781 }
00782
00783 MD5[0] = '\0';
00784 for (i = 0, t = MD5, s = arg; i < 16; i++, t++, s += 2)
00785 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00786
00787 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_FILEMD5S, MD5, sizeof(MD5));
00788 if (qva->qva_mi == NULL) {
00789 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00790 "fileid", arg);
00791 res = 1;
00792 } else {
00793 res = rpmcliShowMatches(qva, ts);
00794 }
00795 } break;
00796
00797 case RPMQV_TID:
00798 { int mybase = 10;
00799 const char * myarg = arg;
00800 char * end = NULL;
00801 unsigned iid;
00802
00803
00804 if (*myarg == '0') {
00805 myarg++;
00806 mybase = 8;
00807 if (*myarg == 'x') {
00808 myarg++;
00809 mybase = 16;
00810 }
00811 }
00812 iid = strtoul(myarg, &end, mybase);
00813 if ((*end) || (end == arg) || (iid == ULONG_MAX)) {
00814 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "tid", arg);
00815 return 1;
00816 }
00817 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_INSTALLTID, &iid, sizeof(iid));
00818 if (qva->qva_mi == NULL) {
00819 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00820 "tid", arg);
00821 res = 1;
00822 } else {
00823 res = rpmcliShowMatches(qva, ts);
00824 }
00825 } break;
00826
00827 case RPMQV_WHATREQUIRES:
00828 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_REQUIRENAME, arg, 0);
00829 if (qva->qva_mi == NULL) {
00830 rpmError(RPMERR_QUERYINFO, _("no package requires %s\n"), arg);
00831 res = 1;
00832 } else {
00833 res = rpmcliShowMatches(qva, ts);
00834 }
00835 break;
00836
00837 case RPMQV_WHATPROVIDES:
00838 if (arg[0] != '/') {
00839 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, arg, 0);
00840 if (qva->qva_mi == NULL) {
00841 rpmError(RPMERR_QUERYINFO, _("no package provides %s\n"), arg);
00842 res = 1;
00843 } else {
00844 res = rpmcliShowMatches(qva, ts);
00845 }
00846 break;
00847 }
00848
00849 case RPMQV_PATH:
00850 { char * fn;
00851
00852 for (s = arg; *s != '\0'; s++)
00853 if (!(*s == '.' || *s == '/'))
00854 break;
00855
00856 if (*s == '\0') {
00857 char fnbuf[PATH_MAX];
00858 fn = realpath(arg, fnbuf);
00859 if (fn)
00860 fn = xstrdup(fn);
00861 else
00862 fn = xstrdup(arg);
00863 } else
00864 fn = xstrdup(arg);
00865 (void) rpmCleanPath(fn);
00866
00867 qva->qva_mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, fn, 0);
00868 if (qva->qva_mi == NULL) {
00869 int myerrno = 0;
00870 if (access(fn, F_OK) != 0)
00871 myerrno = errno;
00872 switch (myerrno) {
00873 default:
00874 rpmError(RPMERR_QUERY,
00875 _("file %s: %s\n"), fn, strerror(myerrno));
00876 break;
00877 case 0:
00878 rpmError(RPMERR_QUERYINFO,
00879 _("file %s is not owned by any package\n"), fn);
00880 break;
00881 }
00882 res = 1;
00883 } else {
00884 res = rpmcliShowMatches(qva, ts);
00885 }
00886 fn = _free(fn);
00887 } break;
00888
00889 case RPMQV_DBOFFSET:
00890 { int mybase = 10;
00891 const char * myarg = arg;
00892 char * end = NULL;
00893 unsigned recOffset;
00894
00895
00896 if (*myarg == '0') {
00897 myarg++;
00898 mybase = 8;
00899 if (*myarg == 'x') {
00900 myarg++;
00901 mybase = 16;
00902 }
00903 }
00904 recOffset = strtoul(myarg, &end, mybase);
00905 if ((*end) || (end == arg) || (recOffset == ULONG_MAX)) {
00906 rpmError(RPMERR_QUERYINFO, _("invalid package number: %s\n"), arg);
00907 return 1;
00908 }
00909 rpmMessage(RPMMESS_DEBUG, _("package record number: %u\n"), recOffset);
00910
00911 qva->qva_mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, &recOffset, sizeof(recOffset));
00912 if (qva->qva_mi == NULL) {
00913 rpmError(RPMERR_QUERYINFO,
00914 _("record %u could not be read\n"), recOffset);
00915 res = 1;
00916 } else {
00917 res = rpmcliShowMatches(qva, ts);
00918 }
00919 } break;
00920
00921 case RPMQV_PACKAGE:
00922
00923 qva->qva_mi = rpmtsInitIterator(ts, RPMDBI_LABEL, arg, 0);
00924 if (qva->qva_mi == NULL) {
00925 rpmError(RPMERR_QUERYINFO, _("package %s is not installed\n"), arg);
00926 res = 1;
00927 } else {
00928 res = rpmcliShowMatches(qva, ts);
00929 }
00930 break;
00931 }
00932
00933
00934 return res;
00935 }
00936
00937
00938 int rpmcliQuery(rpmts ts, QVA_t qva, const char ** argv)
00939 {
00940 const char * arg;
00941 rpmVSFlags vsflags, ovsflags;
00942 int ec = 0;
00943
00944 if (qva->qva_showPackage == NULL)
00945 qva->qva_showPackage = showQueryPackage;
00946
00947 vsflags = rpmExpandNumeric("%{?_vsflags_query}");
00948 if (qva->qva_flags & VERIFY_DIGEST)
00949 vsflags |= _RPMVSF_NODIGESTS;
00950 if (qva->qva_flags & VERIFY_SIGNATURE)
00951 vsflags |= _RPMVSF_NOSIGNATURES;
00952 if (qva->qva_flags & VERIFY_HDRCHK)
00953 vsflags |= RPMVSF_NOHDRCHK;
00954
00955 ovsflags = rpmtsSetVSFlags(ts, vsflags);
00956 if (qva->qva_source == RPMQV_ALL) {
00957
00958 ec = rpmQueryVerify(qva, ts, (const char *) argv);
00959
00960 } else {
00961
00962 if (argv != NULL)
00963 while ((arg = *argv++) != NULL) {
00964 ec += rpmQueryVerify(qva, ts, arg);
00965 rpmtsEmpty(ts);
00966 }
00967
00968 }
00969 vsflags = rpmtsSetVSFlags(ts, ovsflags);
00970
00971 if (qva->qva_showPackage == showQueryPackage)
00972 qva->qva_showPackage = NULL;
00973
00974 return ec;
00975 }