Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

lib/query.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #ifndef PATH_MAX
00009 /*@-incondefs@*/        /* FIX: long int? */
00010 # define PATH_MAX 255
00011 /*@=incondefs@*/
00012 #endif
00013 
00014 #include <rpmcli.h>
00015 #include <rpmbuild.h>
00016 #include "manifest.h"
00017 #include "debug.h"
00018 
00019 /*@access rpmdbMatchIterator@*/         /* XXX compared with NULL */
00020 /*@access Header@*/                     /* XXX compared with NULL */
00021 /*@access rpmdb@*/                      /* XXX compared with NULL */
00022 /*@access FD_t@*/                       /* XXX compared with NULL */
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;  /* important if sizeof(int_32) ! sizeof(time_t) */
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     /* On first call, grab snapshot of now */
00044     if (now == 0) {
00045         now = time(NULL);
00046         tm = localtime(&now);
00047         if (tm) nowtm = *tm;    /* structure assignment */
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     /* this is normally right */
00063     sprintf(sizefield, "%12u", size);
00064 
00065     /* this knows too much about dev_t */
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     /* Convert file mtime to display format */
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 ||  /* Old. */
00087             now < when - 60L * 60L)                     /* In the future.  */
00088         {
00089         /* The file is fairly old or in the future.
00090          * POSIX says the cutoff is 6 months old;
00091          * approximate this by 6*30 days.
00092          * Allow a 1 hour slop factor for what is considered "the future",
00093          * to allow for NFS server/client clock disagreement.
00094          * Show the year instead of the time of day.
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 /*@null@*/ 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     /* XXX rpm-3.3.12 has not RPMTAG_FILEINODES */
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, /*@unused@*/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;         /* XXX FIXME: need real return code */
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             /*@-usereleased@*/
00201             te = stpcpy(te, str);
00202             /*@=usereleased@*/
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, &ltt, (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         /* If querying only docs, skip non-doc files. */
00248         if ((queryFlags & QUERY_FOR_DOCS)
00249           && !(fileFlagsList[i] & RPMFILE_DOC))
00250             continue;
00251 
00252         /* If querying only configs, skip non-config files. */
00253         if ((queryFlags & QUERY_FOR_CONFIG)
00254           && !(fileFlagsList[i] & RPMFILE_CONFIG))
00255             continue;
00256 
00257         /* If not querying %ghost, skip ghost files. */
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                     /*@innerbreak@*/ 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             /*@-unqualifiedtrans@*/
00448             sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
00449             /*@=unqualifiedtrans@*/
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                 /*@-unqualifiedtrans@*/
00462                 sl->sl_lines[t->t_startx + j] =
00463                         _free(sl->sl_lines[t->t_startx + j]);
00464                 /*@=unqualifiedtrans@*/
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         /* XXX don't print query tags twice. */
00503         for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
00504             if (t->name == NULL)        /* XXX programmer error. */
00505                 continue;
00506             if (!strcmp(t->name, ext->name))
00507                 /*@innerbreak@*/ 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         /*@-nullpass@*/
00523         if ((rc = showPackage(qva, rpmdbGetIteratorRpmDB(mi), h)) != 0)
00524             ec = rc;
00525         /*@=nullpass@*/
00526     }
00527     mi = rpmdbFreeIterator(mi);
00528     return ec;
00529 }
00530 
00531 /*@-redecl@*/
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 /*@null@*/ Spec (*freeSpecVec) (Spec spec) = NULL;
00542 /*@=redecl@*/
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             /* Try to read the header from a package file. */
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                 /*@loopbreak@*/ break;
00581             }
00582 
00583             /*@-mustmod@*/      /* LCL: segfault. */
00584             rpmrc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
00585             /*@=mustmod@*/
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                 /*@loopbreak@*/ 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                 /*@loopbreak@*/ break;
00598             }
00599 
00600             /* Query a package file. */
00601             if (rpmrc == RPMRC_OK) {
00602                 retcode = showPackage(qva, rpmdb, h);
00603                 h = headerFree(h);
00604                 continue;
00605             }
00606 
00607             /* Try to read a package manifest. */
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                 /*@loopbreak@*/ break;
00615             }
00616             
00617             /* Read list of packages from manifest. */
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             /* If successful, restart the query loop. */
00627             if (retcode == 0)
00628                 goto restart;
00629 
00630             /*@loopbreak@*/ 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         /* XXX Eliminate linkage dependency loop */
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         /* RPMDBI_PACKAGES */
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                 /*@loopbreak@*/ 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         /*@fallthrough@*/
00742     case RPMQV_PATH:
00743     {   const char * s;
00744         char * fn;
00745 
00746         for (s = arg; *s != '\0'; s++)
00747             if (!(*s == '.' || *s == '/'))
00748                 /*@loopbreak@*/ break;
00749 
00750         if (*s == '\0') {
00751             char fnbuf[PATH_MAX];
00752             fn = /*@-unrecog@*/ realpath(arg, fnbuf) /*@=unrecog@*/;
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         /* XXX should be in strtoul */
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         /* RPMDBI_PACKAGES */
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         /* XXX HACK to get rpmdbFindByLabel out of the API */
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 }

Generated on Wed Mar 13 15:34:48 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002