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