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 = "(unkown error)";
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
00457 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00458 if (msgstr == NULL) {
00459 rpmError(RPMERR_QFMT, _("can't query %s: %s\n"), tn, errstr);
00460 return;
00461 }
00462
00463 switch(t->t_tag) {
00464 case RPMTAG_SUMMARY:
00465 case RPMTAG_GROUP:
00466
00467 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
00468
00469 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG))
00470 continue;
00471 { char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr));
00472 (void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr);
00473 sl->sl_lines[t->t_startx] = buf;
00474 }
00475 break;
00476 case RPMTAG_DESCRIPTION:
00477 for (j = 1; j < t->t_nlines; j++) {
00478 if (*sl->sl_lines[t->t_startx + j] == '%')
00479 continue;
00480
00481 sl->sl_lines[t->t_startx + j] =
00482 _free(sl->sl_lines[t->t_startx + j]);
00483
00484 }
00485 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) {
00486 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
00487 continue;
00488 }
00489 sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr);
00490 if (t->t_nlines > 2)
00491 sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n");
00492 break;
00493 }
00494 }
00495
00496 msgstr = _free(msgstr);
00497
00498 for (i = 0; i < sl->sl_nlines; i++) {
00499 const char * s = sl->sl_lines[i];
00500 if (s == NULL)
00501 continue;
00502 printf("%s", s);
00503 if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n')
00504 printf("\n");
00505 }
00506 }
00507
00508 void rpmDisplayQueryTags(FILE * fp)
00509 {
00510 const struct headerTagTableEntry_s * t;
00511 int i;
00512 const struct headerSprintfExtension_s * ext = rpmHeaderFormats;
00513
00514 for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++)
00515 if (t->name) fprintf(fp, "%s\n", t->name + 7);
00516
00517 while (ext->name != NULL) {
00518 if (ext->type == HEADER_EXT_MORE) {
00519 ext = ext->u.more;
00520 continue;
00521 }
00522
00523 for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
00524 if (t->name == NULL)
00525 continue;
00526 if (!strcmp(t->name, ext->name))
00527 break;
00528 }
00529 if (i >= rpmTagTableSize && ext->type == HEADER_EXT_TAG)
00530 fprintf(fp, "%s\n", ext->name + 7);
00531 ext++;
00532 }
00533 }
00534
00535 int showMatches(QVA_t qva, rpmdbMatchIterator mi, QVF_t showPackage)
00536 {
00537 Header h;
00538 int ec = 0;
00539
00540 while ((h = rpmdbNextIterator(mi)) != NULL) {
00541 int rc;
00542
00543 if ((rc = showPackage(qva, rpmdbGetIteratorRpmDB(mi), h)) != 0)
00544 ec = rc;
00545
00546 }
00547 mi = rpmdbFreeIterator(mi);
00548 return ec;
00549 }
00550
00556 static inline unsigned char nibble(char c)
00557
00558 {
00559 if (c >= '0' && c <= '9')
00560 return (c - '0');
00561 if (c >= 'A' && c <= 'F')
00562 return (c - 'A') + 10;
00563 if (c >= 'a' && c <= 'f')
00564 return (c - 'a') + 10;
00565 return 0;
00566 }
00567
00568
00572 int (*parseSpecVec) (Spec *specp, const char *specFile, const char *rootdir,
00573 const char *buildRoot, int recursing, const char *passPhrase,
00574 char *cookie, int anyarch, int force) = NULL;
00578 Spec (*freeSpecVec) (Spec spec) = NULL;
00579
00580
00581 int rpmQueryVerify(QVA_t qva, rpmQVSources source, const char * arg,
00582 rpmdb rpmdb, QVF_t showPackage)
00583 {
00584 rpmdbMatchIterator mi = NULL;
00585 Header h;
00586 int rc;
00587 int isSource;
00588 int retcode = 0;
00589 const char ** av = NULL;
00590 char * end = NULL;
00591 const char * s;
00592 int i;
00593
00594 switch (source) {
00595 case RPMQV_RPM:
00596 { int ac = 0;
00597 const char * fileURL = NULL;
00598 rpmRC rpmrc;
00599
00600 rc = rpmGlob(arg, &ac, &av);
00601 if (rc) return 1;
00602
00603 restart:
00604 for (i = 0; i < ac; i++) {
00605 FD_t fd;
00606
00607 fileURL = _free(fileURL);
00608 fileURL = av[i];
00609 av[i] = NULL;
00610
00611
00612 fd = Fopen(fileURL, "r.ufdio");
00613 if (fd == NULL || Ferror(fd)) {
00614 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
00615 Fstrerror(fd));
00616 if (fd) (void) Fclose(fd);
00617 retcode = 1;
00618 break;
00619 }
00620
00621
00622 rpmrc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
00623
00624 (void) Fclose(fd);
00625
00626 if (!(rpmrc == RPMRC_OK || rpmrc == RPMRC_BADMAGIC)) {
00627 rpmError(RPMERR_QUERY, _("query of %s failed\n"), fileURL);
00628 retcode = 1;
00629 break;
00630 }
00631 if (rpmrc == RPMRC_OK && h == NULL) {
00632 rpmError(RPMERR_QUERY,
00633 _("old format source packages cannot be queried\n"));
00634 retcode = 1;
00635 break;
00636 }
00637
00638
00639 if (rpmrc == RPMRC_OK) {
00640 retcode = showPackage(qva, rpmdb, h);
00641 h = headerFree(h);
00642 continue;
00643 }
00644
00645
00646 fd = Fopen(fileURL, "r.fpio");
00647 if (fd == NULL || Ferror(fd)) {
00648 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
00649 Fstrerror(fd));
00650 if (fd) (void) Fclose(fd);
00651 retcode = 1;
00652 break;
00653 }
00654
00655
00656 retcode = rpmReadPackageManifest(fd, &ac, &av);
00657 if (retcode) {
00658 rpmError(RPMERR_MANIFEST, _("%s: read manifest failed: %s\n"),
00659 fileURL, Fstrerror(fd));
00660 retcode = 1;
00661 }
00662 (void) Fclose(fd);
00663
00664
00665 if (retcode == 0)
00666 goto restart;
00667
00668 break;
00669 }
00670
00671 fileURL = _free(fileURL);
00672 if (av) {
00673 for (i = 0; i < ac; i++)
00674 av[i] = _free(av[i]);
00675 av = _free(av);
00676 }
00677 } break;
00678
00679 case RPMQV_SPECFILE:
00680 if (showPackage != showQueryPackage)
00681 return 1;
00682
00683
00684 if (parseSpecVec == NULL || freeSpecVec == NULL)
00685 return 1;
00686
00687 { Spec spec = NULL;
00688 Package pkg;
00689 char * buildRoot = NULL;
00690 int recursing = 0;
00691 char * passPhrase = "";
00692 char *cookie = NULL;
00693 int anyarch = 1;
00694 int force = 1;
00695
00696 rc = parseSpecVec(&spec, arg, "/", buildRoot, recursing, passPhrase,
00697 cookie, anyarch, force);
00698 if (rc || spec == NULL) {
00699 rpmError(RPMERR_QUERY,
00700 _("query of specfile %s failed, can't parse\n"), arg);
00701 spec = freeSpecVec(spec);
00702 retcode = 1;
00703 break;
00704 }
00705
00706 if (specedit) {
00707 printNewSpecfile(spec);
00708 spec = freeSpecVec(spec);
00709 retcode = 0;
00710 break;
00711 }
00712
00713 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next)
00714 (void) showPackage(qva, NULL, pkg->header);
00715 spec = freeSpecVec(spec);
00716 } break;
00717
00718 case RPMQV_ALL:
00719
00720 mi = rpmdbInitIterator(rpmdb, RPMDBI_PACKAGES, NULL, 0);
00721 if (mi == NULL) {
00722 rpmError(RPMERR_QUERYINFO, _("no packages\n"));
00723 retcode = 1;
00724 } else {
00725 for (av = (const char **) arg; av && *av; av++) {
00726 if (!rpmdbSetIteratorRE(mi, RPMTAG_NAME, RPMMIRE_DEFAULT, *av))
00727 continue;
00728 mi = rpmdbFreeIterator(mi);
00729 retcode = 1;
00730 break;
00731 }
00732 if (!retcode)
00733 retcode = showMatches(qva, mi, showPackage);
00734 }
00735 break;
00736
00737 case RPMQV_GROUP:
00738 mi = rpmdbInitIterator(rpmdb, RPMTAG_GROUP, arg, 0);
00739 if (mi == NULL) {
00740 rpmError(RPMERR_QUERYINFO,
00741 _("group %s does not contain any packages\n"), arg);
00742 retcode = 1;
00743 } else {
00744 retcode = showMatches(qva, mi, showPackage);
00745 }
00746 break;
00747
00748 case RPMQV_TRIGGEREDBY:
00749 mi = rpmdbInitIterator(rpmdb, RPMTAG_TRIGGERNAME, arg, 0);
00750 if (mi == NULL) {
00751 rpmError(RPMERR_QUERYINFO, _("no package triggers %s\n"), arg);
00752 retcode = 1;
00753 } else {
00754 retcode = showMatches(qva, mi, showPackage);
00755 }
00756 break;
00757
00758 case RPMQV_PKGID:
00759 { unsigned char md5[16];
00760 unsigned char * t;
00761
00762 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00763 {};
00764 if (i != 32) {
00765 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "pkgid", arg);
00766 return 1;
00767 }
00768
00769 md5[0] = '\0';
00770 for (i = 0, t = md5, s = arg; i < 16; i++, t++, s += 2)
00771 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00772
00773 mi = rpmdbInitIterator(rpmdb, RPMTAG_SIGMD5, md5, sizeof(md5));
00774 if (mi == NULL) {
00775 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00776 "pkgid", arg);
00777 retcode = 1;
00778 } else {
00779 retcode = showMatches(qva, mi, showPackage);
00780 }
00781 } break;
00782
00783 case RPMQV_HDRID:
00784 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00785 {};
00786 if (i != 40) {
00787 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "hdrid", arg);
00788 return 1;
00789 }
00790
00791 mi = rpmdbInitIterator(rpmdb, RPMTAG_SHA1HEADER, arg, 0);
00792 if (mi == NULL) {
00793 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00794 "hdrid", arg);
00795 retcode = 1;
00796 } else {
00797 retcode = showMatches(qva, mi, showPackage);
00798 }
00799 break;
00800
00801 case RPMQV_FILEID:
00802 { unsigned char md5[16];
00803 unsigned char * t;
00804
00805 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00806 {};
00807 if (i != 32) {
00808 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "fileid", arg);
00809 return 1;
00810 }
00811
00812 md5[0] = '\0';
00813 for (i = 0, t = md5, s = arg; i < 16; i++, t++, s += 2)
00814 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00815
00816 mi = rpmdbInitIterator(rpmdb, RPMTAG_FILEMD5S, md5, sizeof(md5));
00817 if (mi == NULL) {
00818 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00819 "fileid", arg);
00820 retcode = 1;
00821 } else {
00822 retcode = showMatches(qva, mi, showPackage);
00823 }
00824 } break;
00825
00826 case RPMQV_TID:
00827 { int mybase = 10;
00828 const char * myarg = arg;
00829 unsigned iid;
00830
00831
00832 if (*myarg == '0') {
00833 myarg++;
00834 mybase = 8;
00835 if (*myarg == 'x') {
00836 myarg++;
00837 mybase = 16;
00838 }
00839 }
00840 iid = strtoul(myarg, &end, mybase);
00841 if ((*end) || (end == arg) || (iid == ULONG_MAX)) {
00842 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "tid", arg);
00843 return 1;
00844 }
00845 mi = rpmdbInitIterator(rpmdb, RPMTAG_INSTALLTID, &iid, sizeof(iid));
00846 if (mi == NULL) {
00847 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00848 "tid", arg);
00849 retcode = 1;
00850 } else {
00851 retcode = showMatches(qva, mi, showPackage);
00852 }
00853 } break;
00854
00855 case RPMQV_WHATREQUIRES:
00856 mi = rpmdbInitIterator(rpmdb, RPMTAG_REQUIRENAME, arg, 0);
00857 if (mi == NULL) {
00858 rpmError(RPMERR_QUERYINFO, _("no package requires %s\n"), arg);
00859 retcode = 1;
00860 } else {
00861 retcode = showMatches(qva, mi, showPackage);
00862 }
00863 break;
00864
00865 case RPMQV_WHATPROVIDES:
00866 mi = rpmdbInitIterator(rpmdb, RPMTAG_PROVIDENAME, arg, 0);
00867 if (mi == NULL) {
00868 if (arg[0] != '/')
00869 rpmError(RPMERR_QUERYINFO, _("no package provides %s\n"), arg);
00870 retcode = 1;
00871 } else {
00872 retcode = showMatches(qva, mi, showPackage);
00873 }
00874 if (arg[0] != '/')
00875 break;
00876 retcode = 0;
00877
00878 case RPMQV_PATH:
00879 { char * fn;
00880
00881 for (s = arg; *s != '\0'; s++)
00882 if (!(*s == '.' || *s == '/'))
00883 break;
00884
00885 if (*s == '\0') {
00886 char fnbuf[PATH_MAX];
00887 fn = realpath(arg, fnbuf) ;
00888 if (fn)
00889 fn = xstrdup(fn);
00890 else
00891 fn = xstrdup(arg);
00892 } else
00893 fn = xstrdup(arg);
00894 (void) rpmCleanPath(fn);
00895
00896 mi = rpmdbInitIterator(rpmdb, RPMTAG_BASENAMES, fn, 0);
00897 if (mi == NULL) {
00898 int myerrno = 0;
00899 if (access(fn, F_OK) != 0)
00900 myerrno = errno;
00901 switch (myerrno) {
00902 default:
00903 rpmError(RPMERR_QUERY,
00904 _("file %s: %s\n"), fn, strerror(myerrno));
00905 break;
00906 case 0:
00907 rpmError(RPMERR_QUERYINFO,
00908 _("file %s is not owned by any package\n"), fn);
00909 break;
00910 }
00911 retcode = 1;
00912 } else {
00913 retcode = showMatches(qva, mi, showPackage);
00914 }
00915 fn = _free(fn);
00916 } break;
00917
00918 case RPMQV_DBOFFSET:
00919 { int mybase = 10;
00920 const char * myarg = arg;
00921 unsigned recOffset;
00922
00923
00924 if (*myarg == '0') {
00925 myarg++;
00926 mybase = 8;
00927 if (*myarg == 'x') {
00928 myarg++;
00929 mybase = 16;
00930 }
00931 }
00932 recOffset = strtoul(myarg, &end, mybase);
00933 if ((*end) || (end == arg) || (recOffset == ULONG_MAX)) {
00934 rpmError(RPMERR_QUERYINFO, _("invalid package number: %s\n"), arg);
00935 return 1;
00936 }
00937 rpmMessage(RPMMESS_DEBUG, _("package record number: %u\n"), recOffset);
00938 mi = rpmdbInitIterator(rpmdb, RPMDBI_PACKAGES, &recOffset, sizeof(recOffset));
00939 if (mi == NULL) {
00940 rpmError(RPMERR_QUERYINFO,
00941 _("record %u could not be read\n"), recOffset);
00942 retcode = 1;
00943 } else {
00944 retcode = showMatches(qva, mi, showPackage);
00945 }
00946 } break;
00947
00948 case RPMQV_PACKAGE:
00949
00950 mi = rpmdbInitIterator(rpmdb, RPMDBI_LABEL, arg, 0);
00951 if (mi == NULL) {
00952 rpmError(RPMERR_QUERYINFO, _("package %s is not installed\n"), arg);
00953 retcode = 1;
00954 } else {
00955 retcode = showMatches(qva, mi, showPackage);
00956 }
00957 break;
00958 }
00959
00960 return retcode;
00961 }
00962
00963 int rpmQuery(QVA_t qva, rpmQVSources source, const char * arg)
00964 {
00965 rpmdb rpmdb = NULL;
00966 int rc;
00967
00968 switch (source) {
00969 case RPMQV_RPM:
00970 case RPMQV_SPECFILE:
00971 break;
00972 default:
00973 if (rpmdbOpen(qva->qva_prefix, &rpmdb, O_RDONLY, 0644))
00974 return 1;
00975 break;
00976 }
00977
00978 rc = rpmQueryVerify(qva, source, arg, rpmdb, showQueryPackage);
00979
00980 if (rpmdb != NULL)
00981 (void) rpmdbClose(rpmdb);
00982
00983 return rc;
00984 }