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 = "(unknown 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, int preprocess) = 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 if (rpmExpandNumeric("%{!?_disable_glob_query:%{?_enable_glob_query:1}}"))
00597 {
00598 int ac = 0;
00599 const char * fileURL = NULL;
00600 rpmRC rpmrc;
00601
00602 rc = rpmGlob(arg, &ac, &av);
00603 if (rc) return 1;
00604
00605 restart:
00606 for (i = 0; i < ac; i++) {
00607 FD_t fd;
00608
00609 fileURL = _free(fileURL);
00610 fileURL = av[i];
00611 av[i] = NULL;
00612
00613
00614 fd = Fopen(fileURL, "r.ufdio");
00615 if (fd == NULL || Ferror(fd)) {
00616 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
00617 Fstrerror(fd));
00618 if (fd) (void) Fclose(fd);
00619 retcode = 1;
00620 break;
00621 }
00622
00623
00624 rpmrc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
00625
00626 (void) Fclose(fd);
00627
00628 if (!(rpmrc == RPMRC_OK || rpmrc == RPMRC_BADMAGIC)) {
00629 rpmError(RPMERR_QUERY, _("query of %s failed\n"), fileURL);
00630 retcode = 1;
00631 break;
00632 }
00633 if (rpmrc == RPMRC_OK && h == NULL) {
00634 rpmError(RPMERR_QUERY,
00635 _("old format source packages cannot be queried\n"));
00636 retcode = 1;
00637 break;
00638 }
00639
00640
00641 if (rpmrc == RPMRC_OK) {
00642 retcode = showPackage(qva, rpmdb, h);
00643 h = headerFree(h);
00644 continue;
00645 }
00646
00647
00648 fd = Fopen(fileURL, "r.fpio");
00649 if (fd == NULL || Ferror(fd)) {
00650 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
00651 Fstrerror(fd));
00652 if (fd) (void) Fclose(fd);
00653 retcode = 1;
00654 break;
00655 }
00656
00657
00658 retcode = rpmReadPackageManifest(fd, &ac, &av);
00659 if (retcode) {
00660 rpmError(RPMERR_MANIFEST, _("%s: read manifest failed: %s\n"),
00661 fileURL, Fstrerror(fd));
00662 retcode = 1;
00663 }
00664 (void) Fclose(fd);
00665
00666
00667 if (retcode == 0)
00668 goto restart;
00669
00670 break;
00671 }
00672
00673 fileURL = _free(fileURL);
00674 if (av) {
00675 for (i = 0; i < ac; i++)
00676 av[i] = _free(av[i]);
00677 av = _free(av);
00678 }
00679 } else {
00680 const char * fileURL = arg;
00681 rpmRC rpmrc;
00682
00683
00684 FD_t fd = Fopen(fileURL, "r.ufdio");
00685 if (fd == NULL || Ferror(fd)) {
00686 rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), fileURL,
00687 Fstrerror(fd));
00688 if (fd) (void) Fclose(fd);
00689 retcode = 1;
00690 break;
00691 }
00692
00693
00694 rpmrc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
00695
00696 (void) Fclose(fd);
00697
00698 if (!(rpmrc == RPMRC_OK || rpmrc == RPMRC_BADMAGIC)) {
00699 rpmError(RPMERR_QUERY, _("query of %s failed\n"), fileURL);
00700 retcode = 1;
00701 break;
00702 }
00703 if (rpmrc == RPMRC_OK && h == NULL) {
00704 rpmError(RPMERR_QUERY,
00705 _("old format source packages cannot be queried\n"));
00706 retcode = 1;
00707 break;
00708 }
00709
00710
00711 if (rpmrc == RPMRC_OK) {
00712 retcode = showPackage(qva, rpmdb, h);
00713 h = headerFree(h);
00714 break;
00715 }
00716 } break;
00717
00718 case RPMQV_SPECFILE:
00719 if (showPackage != showQueryPackage)
00720 return 1;
00721
00722
00723 if (parseSpecVec == NULL || freeSpecVec == NULL)
00724 return 1;
00725
00726 { Spec spec = NULL;
00727 Package pkg;
00728 char * buildRoot = NULL;
00729 int recursing = 0;
00730 char * passPhrase = "";
00731 char *cookie = NULL;
00732 int anyarch = 1;
00733 int force = 1;
00734 int preprocess = 0;
00735
00736 rc = parseSpecVec(&spec, arg, "/", buildRoot, recursing, passPhrase,
00737 cookie, anyarch, force, preprocess);
00738 if (rc || spec == NULL) {
00739 rpmError(RPMERR_QUERY,
00740 _("query of specfile %s failed, can't parse\n"), arg);
00741 spec = freeSpecVec(spec);
00742 retcode = 1;
00743 break;
00744 }
00745
00746 if (specedit) {
00747 printNewSpecfile(spec);
00748 spec = freeSpecVec(spec);
00749 retcode = 0;
00750 break;
00751 }
00752
00753 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next)
00754 (void) showPackage(qva, NULL, pkg->header);
00755 spec = freeSpecVec(spec);
00756 } break;
00757
00758 case RPMQV_ALL:
00759
00760 mi = rpmdbInitIterator(rpmdb, RPMDBI_PACKAGES, NULL, 0);
00761 if (mi == NULL) {
00762 rpmError(RPMERR_QUERYINFO, _("no packages\n"));
00763 retcode = 1;
00764 } else {
00765 for (av = (const char **) arg; av && *av; av++) {
00766 if (!rpmdbSetIteratorRE(mi, RPMTAG_NAME, RPMMIRE_DEFAULT, *av))
00767 continue;
00768 mi = rpmdbFreeIterator(mi);
00769 retcode = 1;
00770 break;
00771 }
00772 if (!retcode)
00773 retcode = showMatches(qva, mi, showPackage);
00774 }
00775 break;
00776
00777 case RPMQV_GROUP:
00778 mi = rpmdbInitIterator(rpmdb, RPMTAG_GROUP, arg, 0);
00779 if (mi == NULL) {
00780 rpmError(RPMERR_QUERYINFO,
00781 _("group %s does not contain any packages\n"), arg);
00782 retcode = 1;
00783 } else {
00784 retcode = showMatches(qva, mi, showPackage);
00785 }
00786 break;
00787
00788 case RPMQV_TRIGGEREDBY:
00789 mi = rpmdbInitIterator(rpmdb, RPMTAG_TRIGGERNAME, arg, 0);
00790 if (mi == NULL) {
00791 rpmError(RPMERR_QUERYINFO, _("no package triggers %s\n"), arg);
00792 retcode = 1;
00793 } else {
00794 retcode = showMatches(qva, mi, showPackage);
00795 }
00796 break;
00797
00798 case RPMQV_PKGID:
00799 { unsigned char md5[16];
00800 unsigned char * t;
00801
00802 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00803 {};
00804 if (i != 32) {
00805 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "pkgid", arg);
00806 return 1;
00807 }
00808
00809 md5[0] = '\0';
00810 for (i = 0, t = md5, s = arg; i < 16; i++, t++, s += 2)
00811 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00812
00813 mi = rpmdbInitIterator(rpmdb, RPMTAG_SIGMD5, md5, sizeof(md5));
00814 if (mi == NULL) {
00815 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00816 "pkgid", arg);
00817 retcode = 1;
00818 } else {
00819 retcode = showMatches(qva, mi, showPackage);
00820 }
00821 } break;
00822
00823 case RPMQV_HDRID:
00824 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00825 {};
00826 if (i != 40) {
00827 rpmError(RPMERR_QUERYINFO, _("malformed %s: %s\n"), "hdrid", arg);
00828 return 1;
00829 }
00830
00831 mi = rpmdbInitIterator(rpmdb, RPMTAG_SHA1HEADER, arg, 0);
00832 if (mi == NULL) {
00833 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00834 "hdrid", arg);
00835 retcode = 1;
00836 } else {
00837 retcode = showMatches(qva, mi, showPackage);
00838 }
00839 break;
00840
00841 case RPMQV_FILEID:
00842 { unsigned char md5[16];
00843 unsigned char * t;
00844
00845 for (i = 0, s = arg; *s && isxdigit(*s); s++, i++)
00846 {};
00847 if (i != 32) {
00848 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "fileid", arg);
00849 return 1;
00850 }
00851
00852 md5[0] = '\0';
00853 for (i = 0, t = md5, s = arg; i < 16; i++, t++, s += 2)
00854 *t = (nibble(s[0]) << 4) | nibble(s[1]);
00855
00856 mi = rpmdbInitIterator(rpmdb, RPMTAG_FILEMD5S, md5, sizeof(md5));
00857 if (mi == NULL) {
00858 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00859 "fileid", arg);
00860 retcode = 1;
00861 } else {
00862 retcode = showMatches(qva, mi, showPackage);
00863 }
00864 } break;
00865
00866 case RPMQV_TID:
00867 { int mybase = 10;
00868 const char * myarg = arg;
00869 unsigned iid;
00870
00871
00872 if (*myarg == '0') {
00873 myarg++;
00874 mybase = 8;
00875 if (*myarg == 'x') {
00876 myarg++;
00877 mybase = 16;
00878 }
00879 }
00880 iid = strtoul(myarg, &end, mybase);
00881 if ((*end) || (end == arg) || (iid == ULONG_MAX)) {
00882 rpmError(RPMERR_QUERY, _("malformed %s: %s\n"), "tid", arg);
00883 return 1;
00884 }
00885 mi = rpmdbInitIterator(rpmdb, RPMTAG_INSTALLTID, &iid, sizeof(iid));
00886 if (mi == NULL) {
00887 rpmError(RPMERR_QUERYINFO, _("no package matches %s: %s\n"),
00888 "tid", arg);
00889 retcode = 1;
00890 } else {
00891 retcode = showMatches(qva, mi, showPackage);
00892 }
00893 } break;
00894
00895 case RPMQV_WHATREQUIRES:
00896 mi = rpmdbInitIterator(rpmdb, RPMTAG_REQUIRENAME, arg, 0);
00897 if (mi == NULL) {
00898 rpmError(RPMERR_QUERYINFO, _("no package requires %s\n"), arg);
00899 retcode = 1;
00900 } else {
00901 retcode = showMatches(qva, mi, showPackage);
00902 }
00903 break;
00904
00905 case RPMQV_WHATPROVIDES:
00906 mi = rpmdbInitIterator(rpmdb, RPMTAG_PROVIDENAME, arg, 0);
00907 if (mi == NULL) {
00908 if (arg[0] != '/')
00909 rpmError(RPMERR_QUERYINFO, _("no package provides %s\n"), arg);
00910 retcode = 1;
00911 } else {
00912 retcode = showMatches(qva, mi, showPackage);
00913 }
00914 if (arg[0] != '/')
00915 break;
00916
00917 case RPMQV_PATH:
00918 { char * fn;
00919
00920 for (s = arg; *s != '\0'; s++)
00921 if (!(*s == '.' || *s == '/'))
00922 break;
00923
00924 if (*s == '\0') {
00925 char fnbuf[PATH_MAX];
00926 fn = realpath(arg, fnbuf) ;
00927 if (fn)
00928 fn = xstrdup(fn);
00929 else
00930 fn = xstrdup(arg);
00931 } else
00932 fn = xstrdup(arg);
00933 (void) rpmCleanPath(fn);
00934
00935 mi = rpmdbInitIterator(rpmdb, RPMTAG_BASENAMES, fn, 0);
00936 if (mi == NULL) {
00937 int myerrno = 0;
00938 if (access(fn, F_OK) != 0)
00939 myerrno = errno;
00940 switch (myerrno) {
00941 default:
00942 rpmError(RPMERR_QUERY,
00943 _("file %s: %s\n"), fn, strerror(myerrno));
00944 break;
00945 case 0:
00946 switch (source)
00947 {
00948 case RPMQV_PATH:
00949 rpmError(RPMERR_QUERYINFO,
00950 _("file %s is not owned by any package\n"), fn);
00951 break;
00952 default:
00953 if (retcode) rpmError(RPMERR_QUERYINFO,
00954 _("no package provides %s\n"), fn);
00955 break;
00956 }
00957 break;
00958 }
00959 if (RPMQV_PATH == source)
00960 retcode = 1;
00961 } else {
00962 retcode = showMatches(qva, mi, showPackage);
00963 }
00964 fn = _free(fn);
00965 } break;
00966
00967 case RPMQV_DBOFFSET:
00968 { int mybase = 10;
00969 const char * myarg = arg;
00970 unsigned recOffset;
00971
00972
00973 if (*myarg == '0') {
00974 myarg++;
00975 mybase = 8;
00976 if (*myarg == 'x') {
00977 myarg++;
00978 mybase = 16;
00979 }
00980 }
00981 recOffset = strtoul(myarg, &end, mybase);
00982 if ((*end) || (end == arg) || (recOffset == ULONG_MAX)) {
00983 rpmError(RPMERR_QUERYINFO, _("invalid package number: %s\n"), arg);
00984 return 1;
00985 }
00986 rpmMessage(RPMMESS_DEBUG, _("package record number: %u\n"), recOffset);
00987 mi = rpmdbInitIterator(rpmdb, RPMDBI_PACKAGES, &recOffset, sizeof(recOffset));
00988 if (mi == NULL) {
00989 rpmError(RPMERR_QUERYINFO,
00990 _("record %u could not be read\n"), recOffset);
00991 retcode = 1;
00992 } else {
00993 retcode = showMatches(qva, mi, showPackage);
00994 }
00995 } break;
00996
00997 case RPMQV_PACKAGE:
00998
00999 mi = rpmdbInitIterator(rpmdb, RPMDBI_LABEL, arg, 0);
01000 if (mi == NULL) {
01001 rpmError(RPMERR_QUERYINFO, _("package %s is not installed\n"), arg);
01002 retcode = 1;
01003 } else {
01004 retcode = showMatches(qva, mi, showPackage);
01005 }
01006 break;
01007 }
01008
01009 return retcode;
01010 }
01011
01012 int rpmQuery(QVA_t qva, rpmQVSources source, const char * arg)
01013 {
01014 rpmdb rpmdb = NULL;
01015 int rc;
01016
01017 switch (source) {
01018 case RPMQV_RPM:
01019 case RPMQV_SPECFILE:
01020 break;
01021 default:
01022 if (rpmdbOpen(qva->qva_prefix, &rpmdb, O_RDONLY, 0644))
01023 return 1;
01024 break;
01025 }
01026
01027 rc = rpmQueryVerify(qva, source, arg, rpmdb, showQueryPackage);
01028
01029 if (rpmdb != NULL)
01030 (void) rpmdbClose(rpmdb);
01031
01032 return rc;
01033 }