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