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