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