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