rpm 5.3.12
lib/rpmds.c
Go to the documentation of this file.
00001 
00004 #include "system.h"
00005 
00006 #if defined(WITH_CPUINFO)
00007 #include <cpuinfo.h>
00008 #endif
00009 
00010 #if defined(HAVE_GELF_H) && !defined(__FreeBSD__)
00011 #if LIBELF_H_LFS_CONFLICT
00012 /* Some implementations of libelf.h/gelf.h are incompatible with
00013  * the Large File API.
00014  */
00015 # undef _LARGEFILE64_SOURCE
00016 # undef _LARGEFILE_SOURCE
00017 # undef _FILE_OFFSET_BITS
00018 # define _FILE_OFFSET_BITS 32
00019 #endif
00020 
00021 #if defined(__LCLINT__)
00022 typedef long long loff_t;
00023 #endif
00024 #include <gelf.h>
00025 /*
00026  * On Solaris, gelf.h included libelf.h, which #undef'ed the gettext
00027  * convenience macro _().  Repair by repeating (from system.h) just
00028  * the bits that are needed for _() to function.
00029  */
00030 
00031 #if defined(__sun)
00032 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
00033 # define _(Text) gettext (Text)
00034 #else
00035 # define _(Text) Text
00036 #endif /* gettext _() fixup */
00037 #endif
00038 #endif /* HAVE_GELF_H */
00039 
00040 #if defined(HAVE_LIBELF) && !defined(HAVE_GELF_GETVERNAUX) && !defined(__FreeBSD__)
00041 /* We have gelf.h and libelf, but we don't have some of the
00042  * helper functions gelf_getvernaux(), gelf_getverneed(), etc.
00043  * Provide our own simple versions here.
00044  */
00045 
00046 static GElf_Verdef *gelf_getverdef(Elf_Data *data, int offset,
00047                    GElf_Verdef *dst)
00048 {
00049         return (GElf_Verdef *) ((char *) data->d_buf + offset);
00050 }
00051 
00052 static GElf_Verdaux *gelf_getverdaux(Elf_Data *data, int offset,
00053                     GElf_Verdaux *dst)
00054 {
00055         return (GElf_Verdaux *) ((char *) data->d_buf + offset);
00056 }
00057 
00058 static GElf_Verneed *gelf_getverneed(Elf_Data *data, int offset,
00059                     GElf_Verneed *dst)
00060 {
00061         return (GElf_Verneed *) ((char *) data->d_buf + offset);
00062 }
00063 
00064 static GElf_Vernaux *gelf_getvernaux(Elf_Data *data, int offset,
00065                     GElf_Vernaux *dst)
00066 {
00067         return (GElf_Vernaux *) ((char *) data->d_buf + offset);
00068 }
00069 
00070 /* Most non-Linux systems won't have SHT_GNU_verdef or SHT_GNU_verneed,
00071  * but they might have something mostly-equivalent.  Solaris has
00072  * SHT_SUNW_{verdef,verneed}
00073  */
00074 #if !defined(SHT_GNU_verdef) && defined(__sun) && defined(SHT_SUNW_verdef)
00075 # define SHT_GNU_verdef SHT_SUNW_verdef
00076 # define SHT_GNU_verneed SHT_SUNW_verneed
00077 #endif
00078 
00079 #endif /* HAVE_LIBELF && !HAVE_GELF_GETVERNAUX */
00080 
00081 #if !defined(DT_GNU_HASH)
00082 #define DT_GNU_HASH     0x6ffffef5
00083 #endif
00084 
00085 #define _RPMIOB_INTERNAL
00086 #include <rpmiotypes.h>
00087 #include <rpmio_internal.h>     /* XXX fdGetFILE */
00088 #include <rpmcb.h>              /* XXX fnpyKey */
00089 #include <rpmmacro.h>
00090 #include <argv.h>
00091 
00092 #include <rpmtypes.h>
00093 #include <rpmtag.h>
00094 
00095 #define _RPMDS_INTERNAL
00096 #define _RPMEVR_INTERNAL
00097 #define _RPMPRCO_INTERNAL
00098 #include <rpmds.h>
00099 
00100 #include "debug.h"
00101 
00102 /*@access rpmns @*/
00103 /*@access EVR_t @*/
00104 
00105 #define _isspace(_c)    \
00106         ((_c) == ' ' || (_c) == '\t' || (_c) == '\r' || (_c) == '\n')
00107 
00111 /*@unchecked@*/
00112 static int _noisy_range_comparison_debug_message = 0;
00113 
00114 /*@unchecked@*/
00115 int _rpmds_debug = 0;
00116 
00117 /*@unchecked@*/
00118 int _rpmds_nopromote = 1;
00119 
00120 /*@unchecked@*/
00121 /*@-exportheadervar@*/
00122 int _rpmds_unspecified_epoch_noise = 0;
00123 /*@=exportheadervar@*/
00124 
00130 /*@observer@*/
00131 static const char * rpmdsTagName(rpmTag tagN)
00132         /*@*/
00133 {
00134     const char * Type;
00135 
00136     /* XXX Preserve existing names in debugging messages. */
00137     switch (tagN) {
00138     default:                    Type = tagName(tagN);   break;
00139     case RPMTAG_PROVIDENAME:    Type = "Provides";      break;
00140     case RPMTAG_REQUIRENAME:    Type = "Requires";      break;
00141     case RPMTAG_CONFLICTNAME:   Type = "Conflicts";     break;
00142     case RPMTAG_OBSOLETENAME:   Type = "Obsoletes";     break;
00143     case RPMTAG_TRIGGERNAME:    Type = "Triggers";      break;
00144     case RPMTAG_SUGGESTSNAME:   Type = "Suggests";      break;
00145     case RPMTAG_ENHANCESNAME:   Type = "Enhances";      break;
00146     case RPMTAG_DIRNAMES:       Type = "Dirs";          break;
00147     case RPMTAG_BASENAMES:      Type = "Files";         break;
00148     case RPMTAG_FILELINKTOS:    Type = "Linktos";       break;
00149     case 0:                     Type = "Unknown";       break;
00150     }
00151     return Type;
00152 }
00153 
00154 const char * rpmdsType(const rpmds ds)
00155 {
00156     return rpmdsTagName(rpmdsTagN(ds));
00157 }
00158 
00159 static void rpmdsFini(void * _ds)
00160 {
00161     rpmds ds = _ds;
00162 
00163     if (ds->Count > 0) {
00164         ds->N = _free(ds->N);
00165         ds->EVR = _free(ds->EVR);
00166         ds->Flags = _free(ds->Flags);
00167         (void)headerFree(ds->h);
00168         ds->h = NULL;
00169     }
00170 
00171     ds->DNEVR = _free(ds->DNEVR);
00172     ds->ns.str = _free(ds->ns.str);
00173     memset(&ds->ns, 0, sizeof(ds->ns));
00174     ds->A = _free(ds->A);
00175     ds->Color = _free(ds->Color);
00176     ds->Refs = _free(ds->Refs);
00177     ds->Result = _free(ds->Result);
00178     ds->exclude = mireFreeAll(ds->exclude, ds->nexclude);
00179     ds->include = mireFreeAll(ds->include, ds->ninclude);
00180 }
00181 
00182 /*@unchecked@*/ /*@only@*/ /*@null@*/
00183 rpmioPool _rpmdsPool;
00184 
00185 static rpmds rpmdsGetPool(/*@null@*/ rpmioPool pool)
00186         /*@globals _rpmdsPool, fileSystem, internalState @*/
00187         /*@modifies pool, _rpmdsPool, fileSystem, internalState @*/
00188 {
00189     rpmds ds;
00190 
00191     if (_rpmdsPool == NULL) {
00192         _rpmdsPool = rpmioNewPool("ds", sizeof(*ds), -1, _rpmds_debug,
00193                         NULL, NULL, rpmdsFini);
00194         pool = _rpmdsPool;
00195     }
00196     ds = (rpmds) rpmioGetPool(pool, sizeof(*ds));
00197     memset(((char *)ds)+sizeof(ds->_item), 0, sizeof(*ds)-sizeof(ds->_item));
00198     return ds;
00199 }
00200 
00201 static /*@null@*/
00202 const char ** rpmdsDupArgv(/*@null@*/ const char ** argv, int argc)
00203         /*@*/
00204 {
00205     const char ** av;
00206     size_t nb = 0;
00207     int ac = 0;
00208     char * t;
00209 
00210     if (argv == NULL)
00211         return NULL;
00212     for (ac = 0; ac < argc; ac++) {
00213 assert(argv[ac] != NULL);
00214         nb += strlen(argv[ac]) + 1;
00215     }
00216     nb += (ac + 1) * sizeof(*av);
00217 
00218     av = xmalloc(nb);
00219     t = (char *) (av + ac + 1);
00220     for (ac = 0; ac < argc; ac++) {
00221         av[ac] = t;
00222         t = stpcpy(t, argv[ac]) + 1;
00223     }
00224     av[ac] = NULL;
00225 /*@-nullret@*/
00226     return av;
00227 /*@=nullret@*/
00228 }
00229 
00230 rpmds rpmdsNew(Header h, rpmTag tagN, int flags)
00231 {
00232     int scareMem = (flags & 0x1);
00233     int delslash = 1;
00234     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00235     rpmTag tagEVR, tagF;
00236     rpmds ds = NULL;
00237     const char * Type = NULL;
00238     const char ** N;
00239     rpmuint32_t Count;
00240     int xx;
00241 
00242 assert(scareMem == 0);          /* XXX always allocate memory */
00243 
00244     if (tagN == RPMTAG_NAME)
00245         return rpmdsThis(h, tagN, RPMSENSE_EQUAL);
00246 
00247     switch (tagN) {
00248     default:
00249         goto exit;
00250         /*@notreached@*/ break;
00251     case RPMTAG_PROVIDENAME:
00252         tagEVR = RPMTAG_PROVIDEVERSION;
00253         tagF = RPMTAG_PROVIDEFLAGS;
00254         break;
00255     case RPMTAG_REQUIRENAME:
00256         tagEVR = RPMTAG_REQUIREVERSION;
00257         tagF = RPMTAG_REQUIREFLAGS;
00258         break;
00259     case RPMTAG_CONFLICTNAME:
00260         tagEVR = RPMTAG_CONFLICTVERSION;
00261         tagF = RPMTAG_CONFLICTFLAGS;
00262         break;
00263     case RPMTAG_OBSOLETENAME:
00264         tagEVR = RPMTAG_OBSOLETEVERSION;
00265         tagF = RPMTAG_OBSOLETEFLAGS;
00266         break;
00267     case RPMTAG_TRIGGERNAME:
00268         tagEVR = RPMTAG_TRIGGERVERSION;
00269         tagF = RPMTAG_TRIGGERFLAGS;
00270         break;
00271     case RPMTAG_SUGGESTSNAME:
00272         tagEVR = RPMTAG_SUGGESTSVERSION;
00273         tagF = RPMTAG_SUGGESTSFLAGS;
00274         break;
00275     case RPMTAG_ENHANCESNAME:
00276         tagEVR = RPMTAG_ENHANCESVERSION;
00277         tagF = RPMTAG_ENHANCESFLAGS;
00278         break;
00279     case RPMTAG_DIRNAMES:
00280         tagEVR = 0;
00281         tagF = 0;
00282         delslash = (flags & 0x2) ? 0 : 1;
00283         break;
00284     case RPMTAG_BASENAMES:
00285         tagEVR = RPMTAG_DIRNAMES;
00286         tagF = RPMTAG_DIRINDEXES;
00287         break;
00288     case RPMTAG_FILELINKTOS:
00289         tagEVR = RPMTAG_DIRNAMES;
00290         tagF = RPMTAG_DIRINDEXES;
00291         break;
00292     }
00293 
00294     if (Type == NULL)
00295         Type = rpmdsTagName(tagN);
00296 
00297     he->tag = tagN;
00298     xx = headerGet(h, he, 0);
00299     N = he->p.argv;
00300     Count = he->c;
00301     if (xx && N != NULL && Count > 0) {
00302         ds = rpmdsGetPool(_rpmdsPool);
00303         ds->Type = Type;
00304         ds->h = NULL;
00305         ds->i = -1;
00306         ds->DNEVR = NULL;
00307         ds->tagN = tagN;
00308         ds->N = N;
00309         ds->Count = Count;
00310         ds->nopromote = _rpmds_nopromote;
00311 
00312         if (tagEVR > 0) {
00313             he->tag = tagEVR;
00314             xx = headerGet(h, he, 0);
00315             ds->EVR = he->p.argv;
00316         }
00317         if (tagF > 0) {
00318             he->tag = tagF;
00319             xx = headerGet(h, he, 0);
00320             ds->Flags = (evrFlags * ) he->p.ui32p;
00321         }
00322         {
00323             he->tag = RPMTAG_ARCH;
00324             xx = headerGet(h, he, 0);
00325             ds->A = he->p.str;
00326         }
00327         {
00328             he->tag = RPMTAG_BUILDTIME;
00329             xx = headerGet(h, he, 0);
00330             ds->BT = (he->p.ui32p ? he->p.ui32p[0] : 0);
00331             he->p.ptr = _free(he->p.ptr);
00332         }
00333 
00334         if (tagN == RPMTAG_DIRNAMES) {
00335             char * dn;
00336             size_t len;
00337             unsigned i;
00338             /* XXX Dirnames always have trailing '/', trim that here. */
00339             if (delslash)
00340             for (i = 0; i < Count; i++) {
00341                 (void) urlPath(N[i], (const char **)&dn);
00342                 if (dn > N[i])
00343                     N[i] = dn;
00344                 dn = (char *)N[i];
00345                 len = strlen(dn);
00346                 /* XXX don't truncate if parent is / */
00347                 if (len > 1 && dn[len-1] == '/')
00348                     dn[len-1] = '\0';
00349             }
00350         } else
00351         if (tagN == RPMTAG_BASENAMES) {
00352             const char ** av = xcalloc(Count+1, sizeof(*av));
00353             char * dn;
00354             unsigned i;
00355 
00356             for (i = 0; i < Count; i++) {
00357                 (void) urlPath(ds->EVR[ds->Flags[i]], (const char **)&dn);
00358                 av[i] = rpmGenPath(NULL, dn, N[i]);
00359             }
00360             av[Count] = NULL;
00361 
00362 /*@-unqualifiedtrans@*/
00363             N = ds->N = _free(ds->N);
00364 /*@=unqualifiedtrans@*/
00365             N = ds->N = rpmdsDupArgv(av, Count);
00366             av = argvFree(av);
00367             ds->EVR = _free(ds->EVR);
00368             ds->Flags = _free(ds->Flags);
00369         } else
00370         if (tagN == RPMTAG_FILELINKTOS) {
00371             /* XXX Construct the absolute path of the target symlink(s). */
00372             const char ** av = xcalloc(Count+1, sizeof(*av));
00373             unsigned i;
00374 
00375             for (i = 0; i < Count; i++) {
00376                 if (N[i] == NULL || *N[i] == '\0')
00377                     av[i] = xstrdup("");
00378                 else if (*N[i] == '/')
00379                     av[i] = xstrdup(N[i]);
00380                 else if (ds->EVR != NULL && ds->Flags != NULL)
00381                     av[i] = rpmGenPath(NULL, ds->EVR[ds->Flags[i]], N[i]);
00382                 else
00383                     av[i] = xstrdup("");
00384             }
00385             av[Count] = NULL;
00386 
00387 /*@-unqualifiedtrans@*/
00388             N = ds->N = _free(ds->N);
00389 /*@=unqualifiedtrans@*/
00390             N = ds->N = rpmdsDupArgv(av, Count);
00391             av = argvFree(av);
00392             ds->EVR = _free(ds->EVR);
00393             ds->Flags = _free(ds->Flags);
00394         }
00395 
00396 /*@-modfilesys@*/
00397 if (_rpmds_debug < 0)
00398 fprintf(stderr, "*** ds %p\t%s[%d]\n", ds, ds->Type, ds->Count);
00399 /*@=modfilesys@*/
00400 
00401     }
00402 
00403 exit:
00404 /*@-compdef -usereleased@*/     /* FIX: ds->Flags may be NULL */
00405     /*@-nullstate@*/ /* FIX: ds->Flags may be NULL */
00406     ds = rpmdsLink(ds, (ds ? ds->Type : NULL));
00407     /*@=nullstate@*/
00408 
00409     return ds;
00410 /*@=compdef =usereleased@*/
00411 }
00412 
00413 const char * rpmdsNewN(rpmds ds)
00414 {
00415     rpmns ns = &ds->ns;
00416     const char * Name = ds->N[ds->i];
00417     int xx;
00418 
00419     memset(ns, 0, sizeof(*ns));
00420     xx = rpmnsParse(Name, ns);
00421 
00422 /*@-compdef -usereleased@*/ /* FIX: correct annotations for ds->ns shadow */
00423     return ns->N;
00424 /*@=compdef =usereleased@*/
00425 }
00426 
00427 char * rpmdsNewDNEVR(const char * dspfx, rpmds ds)
00428 {
00429     const char * N = rpmdsNewN(ds);
00430     const char * NS = ds->ns.NS;
00431     const char * A = ds->ns.A;
00432     evrFlags dsFlags = 0;
00433     char * tbuf, * t;
00434     size_t nb = 0;
00435 
00436     if (dspfx)  nb += strlen(dspfx) + 1;
00437     if (ds->ns.str[0] == '!')   nb++;
00438     if (NS)     nb += strlen(NS) + sizeof("()") - 1;
00439     if (N)      nb += strlen(N);
00440     if (A) {
00441         if (_rpmns_N_at_A && _rpmns_N_at_A[0])
00442             nb += sizeof(_rpmns_N_at_A[0]);
00443         nb += strlen(A);
00444     }
00445     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
00446     if (ds->Flags != NULL
00447      && (dsFlags = (ds->Flags[ds->i] & RPMSENSE_SENSEMASK)))
00448     {
00449         if (nb) nb++;
00450         if (dsFlags == RPMSENSE_NOTEQUAL)
00451             nb += 2;
00452         else {
00453             if (dsFlags & RPMSENSE_LESS)        nb++;
00454             if (dsFlags & RPMSENSE_GREATER)     nb++;
00455             if (dsFlags & RPMSENSE_EQUAL)       nb++;
00456         }
00457     }
00458 
00459     ds->ns.Flags = dsFlags;
00460 
00461     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
00462     if (ds->EVR != NULL && ds->EVR[ds->i] && *ds->EVR[ds->i]) {
00463         if (nb) nb++;
00464         nb += strlen(ds->EVR[ds->i]);
00465     }
00466 
00467     t = tbuf = xmalloc(nb + 1);
00468     if (dspfx) {
00469         t = stpcpy(t, dspfx);
00470         *t++ = ' ';
00471     }
00472     if (ds->ns.str[0] == '!')
00473         *t++ = '!';
00474     if (NS)
00475         t = stpcpy( stpcpy(t, NS), "(");
00476     if (N)
00477         t = stpcpy(t, N);
00478     if (NS)
00479         t = stpcpy(t, ")");
00480     if (A) {
00481         if (_rpmns_N_at_A && _rpmns_N_at_A[0])
00482             *t++ = _rpmns_N_at_A[0];
00483         t = stpcpy(t, A);
00484     }
00485 
00486     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
00487     if (ds->Flags != NULL && (ds->Flags[ds->i] & RPMSENSE_SENSEMASK)) {
00488         if (t != tbuf)  *t++ = ' ';
00489         if (dsFlags == RPMSENSE_NOTEQUAL)
00490             t = stpcpy(t, "!=");
00491         else {
00492             if (dsFlags & RPMSENSE_LESS)        *t++ = '<';
00493             if (dsFlags & RPMSENSE_GREATER)     *t++ = '>';
00494             if (dsFlags & RPMSENSE_EQUAL)       *t++ = '=';
00495         }
00496     }
00497     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
00498     if (ds->EVR != NULL && ds->EVR[ds->i] && *ds->EVR[ds->i]) {
00499         if (t != tbuf)  *t++ = ' ';
00500         t = stpcpy(t, ds->EVR[ds->i]);
00501     }
00502     *t = '\0';
00503     return tbuf;
00504 }
00505 
00506 rpmds rpmdsThis(Header h, rpmTag tagN, evrFlags Flags)
00507 {
00508     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
00509     rpmds ds = NULL;
00510     const char * Type;
00511     const char * Name, * V, * R;
00512 #ifdef  RPM_VENDOR_MANDRIVA
00513     const char * D = NULL;
00514 #endif
00515     rpmuint32_t E;
00516     const char ** N, ** EVR;
00517     char * t;
00518     size_t nb;
00519     int xx;
00520 
00521     if (tagN == RPMTAG_NAME)
00522         tagN = RPMTAG_PROVIDENAME;
00523 
00524     Type = rpmdsTagName(tagN);
00525 
00526     he->tag = RPMTAG_EPOCH;
00527     xx = headerGet(h, he, 0);
00528     E = (he->p.ui32p ? he->p.ui32p[0] : 0);
00529     he->p.ptr = _free(he->p.ptr);
00530 
00531 #if defined(RPM_VENDOR_MANDRIVA)    
00532     he->tag = RPMTAG_DISTEPOCH;
00533     xx = headerGet(h, he, 0);
00534     D = (he->p.str ? he->p.str : NULL);
00535 #endif
00536 /*@-mods@*/
00537     xx = headerNEVRA(h, &Name, NULL, &V, &R, NULL);
00538 /*@=mods@*/
00539     /* XXX segfault avoidance */
00540     if (Name == NULL)   Name = xstrdup("N");
00541     if (V == NULL)      V = xstrdup("V");
00542     if (R == NULL)      R = xstrdup("R");
00543 
00544     t = xmalloc(sizeof(*N) + strlen(Name) + 1);
00545     N = (const char **) t;
00546     t += sizeof(*N);
00547     *t = '\0';
00548     N[0] = t;
00549     t = stpcpy(t, Name);
00550     Name = _free(Name);
00551 
00552     nb = sizeof(*EVR) + 20 + strlen(V) + strlen(R) + sizeof("-");
00553 #if defined(RPM_VENDOR_MANDRIVA)
00554     nb += (D ? strlen(D) + sizeof(":") : 0);
00555 #endif
00556     t = xmalloc(nb);
00557     EVR = (const char **) t;
00558     t += sizeof(*EVR);
00559     *t = '\0';
00560     EVR[0] = t;
00561     sprintf(t, "%d:", E);
00562     t += strlen(t);
00563     t = stpcpy( stpcpy( stpcpy( t, V), "-"), R);
00564 #if defined(RPM_VENDOR_MANDRIVA)
00565     if (D != NULL) {
00566         t = stpcpy( stpcpy( t, ":"), D);
00567         D = _free(D);
00568     }
00569 #endif
00570     V = _free(V);
00571     R = _free(R);
00572 
00573     ds = rpmdsGetPool(_rpmdsPool);
00574     ds->Type = Type;
00575     ds->tagN = tagN;
00576     ds->Count = 1;
00577     ds->N = N;
00578     ds->EVR = EVR;
00579     ds->Flags = xmalloc(sizeof(*ds->Flags));    ds->Flags[0] = Flags;
00580 
00581     he->tag = RPMTAG_ARCH;
00582     xx = headerGet(h, he, 0);
00583     ds->A = he->p.str;
00584 
00585     he->tag = RPMTAG_BUILDTIME;
00586     xx = headerGet(h, he, 0);
00587     ds->BT = (he->p.ui32p ? he->p.ui32p[0] : 0);
00588     he->p.ptr = _free(he->p.ptr);
00589 
00590     {   char pre[2];
00591         pre[0] = ds->Type[0];
00592         pre[1] = '\0';
00593         /*@-nullstate@*/ /* LCL: ds->Type may be NULL ??? */
00594         ds->i = 0;      /* XXX rpmdsNewN() needs ds->i = 0, not -1 */
00595 /*@i@*/ ds->DNEVR = rpmdsNewDNEVR(pre, ds);
00596         /*@=nullstate@*/
00597     }
00598 
00599     return rpmdsLink(ds, (ds ? ds->Type : NULL));
00600 }
00601 
00602 rpmds rpmdsSingle(rpmTag tagN, const char * N, const char * EVR, evrFlags Flags)
00603 {
00604     rpmds ds = rpmdsGetPool(_rpmdsPool);
00605     const char * Type = rpmdsTagName(tagN);
00606 
00607     ds->Type = Type;
00608     ds->tagN = tagN;
00609     ds->A = NULL;
00610     {   time_t now = time(NULL);
00611         ds->BT = (rpmuint32_t)now;
00612     }
00613     ds->Count = 1;
00614     /*@-assignexpose@*/
00615     ds->N = xcalloc(2, sizeof(*ds->N));         ds->N[0] = N;
00616     ds->EVR = xcalloc(2, sizeof(*ds->EVR));     ds->EVR[0] = EVR;
00617     /*@=assignexpose@*/
00618     ds->Flags = xmalloc(sizeof(*ds->Flags));    ds->Flags[0] = Flags;
00619     {   char t[2];
00620         t[0] = ds->Type[0];
00621         t[1] = '\0';
00622         ds->i = 0;      /* XXX rpmdsNewN() needs ds->i = 0, not -1 */
00623 /*@i@*/ ds->DNEVR = rpmdsNewDNEVR(t, ds);
00624     }
00625 
00626     return rpmdsLink(ds, (ds ? ds->Type : NULL));
00627 }
00628 
00629 int rpmdsCount(const rpmds ds)
00630 {
00631     return (ds != NULL ? ds->Count : 0);
00632 }
00633 
00634 int rpmdsIx(const rpmds ds)
00635 {
00636     return (ds != NULL ? ds->i : -1);
00637 }
00638 
00639 int rpmdsSetIx(rpmds ds, int ix)
00640 {
00641     int i = -1;
00642 
00643     if (ds != NULL) {
00644         i = ds->i;
00645         ds->i = ix;
00646     }
00647     return i;
00648 }
00649 
00650 const char * rpmdsDNEVR(const rpmds ds)
00651 {
00652     const char * DNEVR = NULL;
00653 
00654     if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
00655         if (ds->DNEVR != NULL)
00656             DNEVR = ds->DNEVR;
00657     }
00658     return DNEVR;
00659 }
00660 
00661 const char * rpmdsN(const rpmds ds)
00662 {
00663     const char * N = NULL;
00664 
00665     if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
00666 /*@-globs -mods @*/     /* FIX: correct annotations for ds->ns shadow */
00667         N = (ds->ns.N ? ds->ns.N : rpmdsNewN(ds));
00668 /*@=globs =mods @*/
00669     }
00670     return N;
00671 }
00672 
00673 const char * rpmdsEVR(const rpmds ds)
00674 {
00675     const char * EVR = NULL;
00676 
00677     if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
00678         if (ds->EVR != NULL)
00679             EVR = ds->EVR[ds->i];
00680     }
00681     return EVR;
00682 }
00683 
00684 evrFlags rpmdsFlags(const rpmds ds)
00685 {
00686     evrFlags Flags = 0;
00687 
00688     if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
00689         if (ds->Flags != NULL)
00690             Flags = ds->Flags[ds->i];
00691     }
00692     return Flags;
00693 }
00694 
00695 rpmTag rpmdsTagN(const rpmds ds)
00696 {
00697     rpmTag tagN = 0;
00698 
00699     if (ds != NULL)
00700         tagN = ds->tagN;
00701     return tagN;
00702 }
00703 
00704 const char * rpmdsA(const rpmds ds)
00705 {
00706     const char * A = NULL;
00707 
00708     if (ds != NULL)
00709         A = ds->A;
00710     return A;
00711 }
00712 
00713 time_t rpmdsBT(const rpmds ds)
00714 {
00715     time_t BT = 0;
00716     if (ds != NULL && ds->BT > 0)
00717         BT = ds->BT;
00718     return BT;
00719 }
00720 
00721 time_t rpmdsSetBT(const rpmds ds, time_t BT)
00722 {
00723     time_t oBT = 0;
00724     if (ds != NULL) {
00725         oBT = (time_t)ds->BT;
00726         ds->BT = (rpmuint32_t)BT;
00727     }
00728     return oBT;
00729 }
00730 
00731 nsType rpmdsNSType(const rpmds ds)
00732 {
00733     nsType NSType = RPMNS_TYPE_UNKNOWN;
00734     if (ds != NULL)
00735         NSType = ds->ns.Type;
00736     return NSType;
00737 }
00738 
00739 int rpmdsNoPromote(const rpmds ds)
00740 {
00741     int nopromote = 0;
00742 
00743     if (ds != NULL)
00744         nopromote = ds->nopromote;
00745     return nopromote;
00746 }
00747 
00748 int rpmdsSetNoPromote(rpmds ds, int nopromote)
00749 {
00750     int onopromote = 0;
00751 
00752     if (ds != NULL) {
00753         onopromote = ds->nopromote;
00754         ds->nopromote = nopromote;
00755     }
00756     return onopromote;
00757 }
00758 
00759 void * rpmdsSetEVRparse(rpmds ds,
00760         int (*EVRparse)(const char *evrstr, EVR_t evr))
00761 {
00762     void * oEVRparse = NULL;
00763 
00764     if (ds != NULL) {
00765 /*@i@*/ oEVRparse = ds->EVRparse;
00766 /*@i@*/ ds->EVRparse = EVRparse;
00767     }
00768     return oEVRparse;
00769 }
00770 
00771 void * rpmdsSetEVRcmp(rpmds ds, int (*EVRcmp)(const char *a, const char *b))
00772 {
00773     void * oEVRcmp = NULL;
00774 
00775     if (ds != NULL) {
00776 /*@i@*/ oEVRcmp = ds->EVRcmp;
00777 /*@i@*/ ds->EVRcmp = EVRcmp;
00778     }
00779     return oEVRcmp;
00780 }
00781 
00782 rpmuint32_t rpmdsColor(const rpmds ds)
00783 {
00784     rpmuint32_t Color = 0;
00785 
00786     if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
00787         if (ds->Color != NULL)
00788             Color = ds->Color[ds->i];
00789     }
00790     return Color;
00791 }
00792 
00793 rpmuint32_t rpmdsSetColor(const rpmds ds, rpmuint32_t color)
00794 {
00795     rpmuint32_t ocolor = 0;
00796 
00797     if (ds == NULL)
00798         return ocolor;
00799 
00800     if (ds->Color == NULL && ds->Count > 0)     /* XXX lazy malloc */
00801         ds->Color = xcalloc(ds->Count, sizeof(*ds->Color));
00802 
00803     if (ds->i >= 0 && ds->i < (int)ds->Count) {
00804         if (ds->Color != NULL) {
00805             ocolor = ds->Color[ds->i];
00806             ds->Color[ds->i] = color;
00807         }
00808     }
00809     return ocolor;
00810 }
00811 
00812 void * rpmdsExclude(const rpmds ds)
00813 {
00814     return (ds != NULL ? ds->exclude : NULL);
00815 }
00816 
00817 int rpmdsNExclude(const rpmds ds)
00818 {
00819     return (ds != NULL ? ds->nexclude : 0);
00820 }
00821 
00822 void * rpmdsInclude(const rpmds ds)
00823 {
00824     return (ds != NULL ? ds->include : NULL);
00825 }
00826 
00827 int rpmdsNInclude(const rpmds ds)
00828 {
00829     return (ds != NULL ? ds->ninclude : 0);
00830 }
00831 
00832 rpmuint32_t rpmdsRefs(const rpmds ds)
00833 {
00834     rpmuint32_t Refs = 0;
00835 
00836     if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
00837         if (ds->Refs != NULL)
00838             Refs = ds->Refs[ds->i];
00839     }
00840     return Refs;
00841 }
00842 
00843 rpmuint32_t rpmdsSetRefs(const rpmds ds, rpmuint32_t refs)
00844 {
00845     rpmuint32_t orefs = 0;
00846 
00847     if (ds == NULL)
00848         return orefs;
00849 
00850     if (ds->Refs == NULL && ds->Count > 0)      /* XXX lazy malloc */
00851         ds->Refs = xcalloc(ds->Count, sizeof(*ds->Refs));
00852 
00853     if (ds->i >= 0 && ds->i < (int)ds->Count) {
00854         if (ds->Refs != NULL) {
00855             orefs = ds->Refs[ds->i];
00856             ds->Refs[ds->i] = refs;
00857         }
00858     }
00859     return orefs;
00860 }
00861 
00862 rpmint32_t rpmdsResult(const rpmds ds)
00863 {
00864     rpmint32_t result = 0;
00865 
00866     if (ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count) {
00867         if (ds->Result != NULL)
00868             result = ds->Result[ds->i];
00869     }
00870     return result;
00871 }
00872 
00873 rpmint32_t rpmdsSetResult(const rpmds ds, rpmint32_t result)
00874 {
00875     rpmint32_t oresult = 0;
00876 
00877     if (ds == NULL)
00878         return oresult;
00879 
00880     if (ds->Result == NULL && ds->Count > 0)    /* XXX lazy malloc */
00881         ds->Result = xcalloc(ds->Count, sizeof(*ds->Result));
00882 
00883     if (ds->i >= 0 && ds->i < (int)ds->Count) {
00884         if (ds->Result != NULL) {
00885             oresult = ds->Result[ds->i];
00886             ds->Result[ds->i] = result;
00887         }
00888     }
00889     return oresult;
00890 }
00891 
00892 void rpmdsNotify(rpmds ds, const char * where, int rc)
00893 {
00894     if (!(ds != NULL && ds->i >= 0 && ds->i < (int)ds->Count))
00895         return;
00896     if (ds->DNEVR == NULL)
00897         return;
00898 
00899     rpmlog(RPMLOG_DEBUG, "%9s: %-45s %-s %s\n", rpmdsTagName(ds->tagN),
00900                 (!strcmp(ds->DNEVR, "cached") ? ds->DNEVR : ds->DNEVR+2),
00901                 (rc ? _("NO ") : _("YES")),
00902                 (where != NULL ? where : ""));
00903 }
00904 
00905 int rpmdsNext(/*@null@*/ rpmds ds)
00906         /*@modifies ds @*/
00907 {
00908     int i = -1;
00909 
00910     if (ds != NULL && ++ds->i >= 0) {
00911         if (ds->i < (int)ds->Count) {
00912             char t[2];
00913             i = ds->i;
00914             ds->DNEVR = _free(ds->DNEVR);
00915             ds->ns.str = _free(ds->ns.str);
00916             memset(&ds->ns, 0, sizeof(ds->ns));
00917             t[0] = ((ds->Type != NULL) ? ds->Type[0] : '\0');
00918             t[1] = '\0';
00919             /*@-nullstate@*/
00920            /*@i@*/ ds->DNEVR = rpmdsNewDNEVR(t, ds);
00921             /*@=nullstate@*/
00922 
00923         } else
00924             ds->i = -1;
00925 
00926 /*@-modfilesys @*/
00927 if (_rpmds_debug  < 0 && i != -1 && ds->DNEVR[2] != '\0')
00928 fprintf(stderr, "*** ds %p\t%s[%d]: %s\n", ds, (ds->Type ? ds->Type : "?Type?"), i, (ds->DNEVR ? ds->DNEVR : "?DNEVR?"));
00929 /*@=modfilesys @*/
00930 
00931     }
00932 
00933     return i;
00934 }
00935 
00936 rpmds rpmdsInit(/*@null@*/ rpmds ds)
00937         /*@modifies ds @*/
00938 {
00939     if (ds != NULL)
00940         ds->i = -1;
00941     /*@-refcounttrans@*/
00942     return ds;
00943     /*@=refcounttrans@*/
00944 }
00945 
00946 /*@null@*/
00947 static rpmds rpmdsDup(const rpmds ods)
00948         /*@modifies ods @*/
00949 {
00950     rpmds ds = rpmdsGetPool(_rpmdsPool);
00951     size_t nb;
00952 
00953 /*@-assignexpose -castexpose @*/
00954     ds->h = (ods->h != NULL ? headerLink(ods->h) : NULL);
00955     ds->Type = ods->Type;
00956 /*@=assignexpose =castexpose @*/
00957     ds->tagN = ods->tagN;
00958     ds->Count = ods->Count;
00959     ds->i = ods->i;
00960     ds->l = ods->l;
00961     ds->u = ods->u;
00962 
00963     nb = (ds->Count+1) * sizeof(*ds->N);
00964     ds->N = (ds->h != NULL
00965         ? memcpy(xmalloc(nb), ods->N, nb)
00966         : rpmdsDupArgv(ods->N, ods->Count) );
00967 
00968     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
00969 assert(ods->EVR != NULL);
00970 assert(ods->Flags != NULL);
00971 
00972     nb = (ds->Count+1) * sizeof(*ds->EVR);
00973     ds->EVR = (ds->h != NULL
00974         ? memcpy(xmalloc(nb), ods->EVR, nb)
00975         : rpmdsDupArgv(ods->EVR, ods->Count) );
00976 
00977     nb = (ds->Count * sizeof(*ds->Flags));
00978     ds->Flags = (ds->h != NULL
00979         ? ods->Flags
00980         : memcpy(xmalloc(nb), ods->Flags, nb) );
00981     ds->nopromote = ods->nopromote;
00982 /*@-assignexpose@*/
00983     ds->EVRcmp = ods->EVRcmp;;
00984 /*@=assignexpose@*/
00985 
00986 /*@-compmempass@*/ /* FIX: ds->Flags is kept, not only */
00987     return rpmdsLink(ds, (ds ? ds->Type : NULL));
00988 /*@=compmempass@*/
00989 }
00990 
00991 int rpmdsFind(rpmds ds, const rpmds ods)
00992 {
00993     int comparison;
00994 
00995     if (ds == NULL || ods == NULL)
00996         return -1;
00997 
00998     ds->l = 0;
00999     ds->u = ds->Count;
01000     while (ds->l < ds->u) {
01001         ds->i = (ds->l + ds->u) / 2;
01002 
01003         comparison = strcmp(ods->N[ods->i], ds->N[ds->i]);
01004 
01005         /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
01006 /*@-nullderef@*/
01007         if (comparison == 0 && ods->EVR && ds->EVR)
01008             comparison = strcmp(ods->EVR[ods->i], ds->EVR[ds->i]);
01009         if (comparison == 0 && ods->Flags && ds->Flags)
01010             comparison = (ods->Flags[ods->i] - ds->Flags[ds->i]);
01011 /*@=nullderef@*/
01012 
01013         if (comparison < 0)
01014             ds->u = ds->i;
01015         else if (comparison > 0)
01016             ds->l = ds->i + 1;
01017         else
01018             return ds->i;
01019     }
01020     return -1;
01021 }
01022 
01023 int rpmdsMerge(rpmds * dsp, rpmds ods)
01024 {
01025     rpmds ds;
01026     const char ** N;
01027     const char ** EVR;
01028     evrFlags * Flags;
01029     int j;
01030 int save;
01031 
01032     if (dsp == NULL || ods == NULL)
01033         return -1;
01034 
01035     /* If not initialized yet, dup the 1st entry. */
01036     if (*dsp == NULL) {
01037         save = ods->Count;
01038         ods->Count = 1;
01039         *dsp = rpmdsDup(ods);
01040         ods->Count = save;
01041     }
01042     ds = *dsp;
01043     if (ds == NULL)
01044         return -1;
01045 
01046     /*
01047      * Add new entries.
01048      */
01049 save = ods->i;
01050     ods = rpmdsInit(ods);
01051     if (ods != NULL)
01052     while (rpmdsNext(ods) >= 0) {
01053         /*
01054          * If this entry is already present, don't bother.
01055          */
01056         if (rpmdsFind(ds, ods) >= 0)
01057             continue;
01058 
01059         /*
01060          * Insert new entry.
01061          */
01062         for (j = ds->Count; j > (int)ds->u; j--)
01063             ds->N[j] = ds->N[j-1];
01064         ds->N[ds->u] = ods->N[ods->i];
01065         N = rpmdsDupArgv(ds->N, ds->Count+1);
01066         ds->N = _free(ds->N);
01067         ds->N = N;
01068         
01069         /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
01070 /*@-nullderef -nullpass -nullptrarith @*/
01071 assert(ods->EVR != NULL);
01072 assert(ods->Flags != NULL);
01073 
01074         for (j = ds->Count; j > (int)ds->u; j--)
01075             ds->EVR[j] = ds->EVR[j-1];
01076         ds->EVR[ds->u] = ods->EVR[ods->i];
01077         EVR = rpmdsDupArgv(ds->EVR, ds->Count+1);
01078         ds->EVR = _free(ds->EVR);
01079         ds->EVR = EVR;
01080 
01081         Flags = xmalloc((ds->Count+1) * sizeof(*Flags));
01082         if (ds->u > 0)
01083             memcpy(Flags, ds->Flags, ds->u * sizeof(*Flags));
01084         if (ds->u < ds->Count)
01085             memcpy(Flags + ds->u + 1, ds->Flags + ds->u, (ds->Count - ds->u) * sizeof(*Flags));
01086         Flags[ds->u] = ods->Flags[ods->i];
01087         ds->Flags = _free(ds->Flags);
01088         ds->Flags = Flags;
01089 /*@=nullderef =nullpass =nullptrarith @*/
01090 
01091         ds->i = -1;
01092         ds->Count++;
01093 
01094     }
01095 /*@-nullderef@*/
01096 ods->i = save;
01097 /*@=nullderef@*/
01098     return 0;
01099 }
01100 
01101 int rpmdsSearch(rpmds ds, rpmds ods)
01102 {
01103     int comparison;
01104     int i, l, u;
01105 
01106     if (ds == NULL || ods == NULL)
01107         return -1;
01108 
01109     /* Binary search to find the [l,u) subset that contains N */
01110     i = -1;
01111     l = 0;
01112     u = ds->Count;
01113     while (l < u) {
01114         i = (l + u) / 2;
01115 
01116         comparison = strcmp(ods->N[ods->i], ds->N[i]);
01117 
01118         if (comparison < 0)
01119             u = i;
01120         else if (comparison > 0)
01121             l = i + 1;
01122         else {
01123             /* Set l to 1st member of set that contains N. */
01124             if (strcmp(ods->N[ods->i], ds->N[l]))
01125                 l = i;
01126             while (l > 0 && !strcmp(ods->N[ods->i], ds->N[l-1]))
01127                 l--;
01128             /* Set u to 1st member of set that does not contain N. */
01129             if (u >= (int)ds->Count || strcmp(ods->N[ods->i], ds->N[u]))
01130                 u = i;
01131             while (++u < (int)ds->Count) {
01132                 if (strcmp(ods->N[ods->i], ds->N[u]))
01133                     /*@innerbreak@*/ break;
01134             }
01135             break;
01136         }
01137     }
01138 
01139     /* Check each member of [l,u) subset for ranges overlap. */
01140     i = -1;
01141     if (l < u) {
01142         int save = rpmdsSetIx(ds, l-1);
01143         while ((l = rpmdsNext(ds)) >= 0 && (l < u)) {
01144             if ((i = rpmdsCompare(ods, ds)) != 0)
01145                 break;
01146         }
01147         /* Return element index that overlaps, or -1. */
01148         if (i)
01149             i = rpmdsIx(ds);
01150         else {
01151             (void) rpmdsSetIx(ds, save);
01152             i = -1;
01153         }
01154         /* Save the return value. */
01155         if (ods->Result != NULL)
01156             (void) rpmdsSetResult(ods, (i != -1 ? 1 : 0));
01157     }
01158     return i;
01159 }
01160 
01169 static void rpmdsNSAdd(/*@out@*/ rpmds *dsp, const char * NS,
01170                 const char *N, const char *EVR, evrFlags Flags)
01171         /*@modifies *dsp @*/
01172 {
01173     char *t;
01174     rpmds ds;
01175     int xx;
01176 
01177     t = alloca(strlen(NS)+sizeof("()")+strlen(N));
01178     *t = '\0';
01179     (void) stpcpy( stpcpy( stpcpy( stpcpy(t, NS), "("), N), ")");
01180 
01181     ds = rpmdsSingle(RPMTAG_PROVIDENAME, t, EVR, Flags);
01182     xx = rpmdsMerge(dsp, ds);
01183     (void)rpmdsFree(ds);
01184     ds = NULL;
01185 }
01186 
01187 #if defined(WITH_CPUINFO)
01188 int rpmdsCpuinfo(rpmds *dsp, const char * fn)
01189 {
01190     const char * NS = "cpuinfo";
01191     struct cpuinfo *cip = cpuinfo_new();
01192     cpuinfo_feature_t feature;
01193     char tmp[20];
01194     union _dbswap {
01195         rpmuint32_t ui;
01196         unsigned char uc[4];
01197     };
01198     static union _dbswap orderedbytes = { .ui = 0x11223344 };
01199     const char * endian = NULL;
01200 
01201     snprintf(tmp, 19, "%d", cpuinfo_get_frequency(cip));
01202     tmp[19] = '\0';
01203     rpmdsNSAdd(dsp, NS, "cpu_MHz", tmp, RPMSENSE_PROBE|RPMSENSE_EQUAL);
01204     snprintf(tmp, 19, "%d", cpuinfo_get_cores(cip));
01205     rpmdsNSAdd(dsp, NS, "cpu_cores", tmp, RPMSENSE_PROBE|RPMSENSE_EQUAL);
01206     snprintf(tmp, 19, "%d", cpuinfo_get_threads(cip));
01207     rpmdsNSAdd(dsp, NS, "cpu_threads", tmp, RPMSENSE_PROBE|RPMSENSE_EQUAL);
01208 
01209     if(orderedbytes.uc[0] == 0x44)
01210         endian = "little";
01211     else if(orderedbytes.uc[0] == 0x11)
01212         endian = "big";
01213     else if(orderedbytes.uc[0] == 0x22)
01214         endian = "pdp";
01215     rpmdsNSAdd(dsp, NS, "endian", endian, RPMSENSE_PROBE|RPMSENSE_EQUAL);
01216 
01217     for (feature = cpuinfo_feature_common; feature != cpuinfo_feature_architecture_max; feature++) {
01218         if(feature == cpuinfo_feature_common_max)
01219             feature = cpuinfo_feature_architecture;
01220         if (cpuinfo_has_feature(cip, feature)) {
01221             const char *name = cpuinfo_string_of_feature(feature);
01222             if (name)
01223                 rpmdsNSAdd(dsp, NS, name, "", RPMSENSE_PROBE);
01224         }
01225     }
01226     cpuinfo_destroy(cip);
01227 
01228     return RPMRC_OK;
01229 }    
01230 
01231 #else
01232 
01233 struct cpuinfo_s {
01234 /*@observer@*/ /*@null@*/
01235     const char *name;
01236     int done;
01237     int flags;
01238 };
01239 
01240 /*@unchecked@*/
01241 static struct cpuinfo_s ctags[] = {
01242     { "processor",      0,  0 },
01243     { "vendor_id",      0,  0 },
01244     { "cpu_family",     0,  1 },
01245     { "model",          0,  1 },
01246     { "model_name",     0,  0 },
01247     { "stepping",       0,  1 },
01248     { "cpu_MHz",        0,  1 },
01249     { "cache_size",     0,  1 },
01250     { "physical_id",    0,  0 },
01251     { "siblings",       0,  0 },
01252     { "core_id",        0,  0 },
01253     { "cpu_cores",      0,  0 },
01254     { "fdiv_bug",       0,  3 },
01255     { "hlt_bug",        0,  3 },
01256     { "f00f_bug",       0,  3 },
01257     { "coma_bug",       0,  3 },
01258     { "fpu",            0,  0 },        /* XXX use flags attribute instead. */
01259     { "fpu_exception",  0,  3 },
01260     { "cpuid_level",    0,  0 },
01261     { "wp",             0,  3 },
01262     { "flags",          0,  4 },
01263     { "bogomips",       0,  1 },
01264     { "clflush_size",   0,  1 },
01265     { NULL,             0, -1 }
01266 };
01267 
01273 static int rpmdsCpuinfoCtagFlags(const char * name)
01274         /*@globals ctags @*/
01275         /*@modifies ctags @*/
01276 {
01277     struct cpuinfo_s * ct;
01278     int flags = -1;
01279 
01280     for (ct = ctags; ct->name != NULL; ct++) {
01281         if (strcmp(ct->name, name))
01282             continue;
01283         if (ct->done)
01284             continue;
01285         ct->done = 1;           /* XXX insure single occurrence */
01286         flags = ct->flags;
01287         break;
01288     }
01289     return flags;
01290 }
01291 
01292 #define _PROC_CPUINFO   "/proc/cpuinfo"
01293 
01295 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
01296 const char * _cpuinfo_path = NULL;
01297 
01298 int rpmdsCpuinfo(rpmds *dsp, const char * fn)
01299         /*@globals _cpuinfo_path, ctags @*/
01300         /*@modifies _cpuinfo_path, ctags @*/
01301 {
01302     struct cpuinfo_s * ct;
01303     const char * NS = "cpuinfo";
01304     rpmiob iob = NULL;
01305     char * f, * fe, * fend;
01306     char * g, * ge;
01307     char * t;
01308     int rc = -1;
01309     int xx;
01310 
01311 /*@-modobserver@*/
01312     if (_cpuinfo_path == NULL) {
01313         _cpuinfo_path = rpmExpand("%{?_rpmds_cpuinfo_path}", NULL);
01314         /* XXX may need to validate path existence somewhen. */
01315         if (!(_cpuinfo_path != NULL && *_cpuinfo_path == '/')) {
01316 /*@-observertrans @*/
01317             _cpuinfo_path = _free(_cpuinfo_path);
01318 /*@=observertrans @*/
01319             _cpuinfo_path = xstrdup(_PROC_CPUINFO);
01320         }
01321     }
01322 /*@=modobserver@*/
01323 
01324     if (fn == NULL)
01325         fn = _cpuinfo_path;
01326 
01327     /* Reset done variables. */
01328     for (ct = ctags; ct->name != NULL; ct++)
01329         ct->done = 0;
01330 
01331     xx = rpmiobSlurp(fn, &iob);
01332     if (!(xx == 0 && iob != NULL))
01333         goto exit;
01334 
01335     for (f = (char *)iob->b; *f != '\0'; f = fend) {
01336         /* find EOL */
01337         fe = f;
01338         while (*fe != '\0' && !(*fe == '\n' || *fe == '\r'))
01339             fe++;
01340         ge = fe;
01341         while (*fe != '\0' && (*fe == '\n' || *fe == '\r'))
01342             *fe++ = '\0';
01343         fend = fe;
01344 
01345         /* rtrim on line. */
01346         while (--ge > f && _isspace(*ge))
01347             *ge = '\0';
01348 
01349         /* ltrim on line. */
01350         while (*f && _isspace(*f))
01351             f++;
01352 
01353         /* split on ':' */
01354         fe = f;
01355         while (*fe && *fe != ':')
01356             fe++;
01357         if (*fe == '\0')
01358             continue;
01359         g = fe + 1;
01360 
01361         /* rtrim on field 1. */
01362         *fe = '\0';
01363         while (--fe > f && _isspace(*fe))
01364             *fe = '\0';
01365         if (*f == '\0')
01366             continue;
01367 
01368         /* ltrim on field 2. */
01369         while (*g && _isspace(*g))
01370             g++;
01371         if (*g == '\0')
01372             continue;
01373 
01374         for (t = f; *t != '\0'; t++) {
01375             if (_isspace(*t))
01376                 *t = '_';
01377         }
01378 
01379         switch (rpmdsCpuinfoCtagFlags(f)) {
01380         case -1:        /* not found */
01381         case 0:         /* ignore */
01382         default:
01383             continue;
01384             /*@notreached@*/ /*@switchbreak@*/ break;
01385         case 1:         /* Provides: cpuinfo(f) = g */
01386             for (t = g; *t != '\0'; t++) {
01387                 if (_isspace(*t) || *t == '(' || *t == ')')
01388                     *t = '_';
01389             }
01390             rpmdsNSAdd(dsp, NS, f, g, RPMSENSE_PROBE|RPMSENSE_EQUAL);
01391             /*@switchbreak@*/ break;
01392         case 2:         /* Provides: cpuinfo(g) */
01393             for (t = g; *t != '\0'; t++) {
01394                 if (_isspace(*t) || *t == '(' || *t == ')')
01395                     *t = '_';
01396             }
01397             rpmdsNSAdd(dsp, NS, g, "", RPMSENSE_PROBE);
01398             /*@switchbreak@*/ break;
01399         case 3:         /* if ("yes") Provides: cpuinfo(f) */
01400            if (!strcmp(g, "yes"))
01401                 rpmdsNSAdd(dsp, NS, f, "", RPMSENSE_PROBE);
01402             /*@switchbreak@*/ break;
01403         case 4:         /* Provides: cpuinfo(g[i]) */
01404         {   char ** av = NULL;
01405             int i = 0;
01406             rc = poptParseArgvString(g, NULL, (const char ***)&av);
01407             if (!rc && av != NULL)
01408             while ((t = av[i++]) != NULL)
01409                 rpmdsNSAdd(dsp, NS, t, "", RPMSENSE_PROBE);
01410             t = NULL;
01411             if (av != NULL)
01412                 free(av);
01413         }   /*@switchbreak@*/ break;
01414         }
01415     }
01416 
01417 exit:
01418     iob = rpmiobFree(iob);
01419     return rc;
01420 }
01421 #endif
01422 
01423 struct rpmlibProvides_s {
01424 /*@observer@*/ /*@relnull@*/
01425     const char * featureName;
01426 /*@observer@*/ /*@relnull@*/
01427     const char * featureEVR;
01428     evrFlags featureFlags;
01429 /*@observer@*/ /*@relnull@*/
01430     const char * featureDescription;
01431 };
01432 
01433 /*@unchecked@*/ /*@observer@*/
01434 static struct rpmlibProvides_s rpmlibProvides[] = {
01435     { "rpmlib(VersionedDependencies)",  "3.0.3-1",
01436         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01437     N_("PreReq:, Provides:, and Obsoletes: dependencies support versions.") },
01438     { "rpmlib(CompressedFileNames)",    "3.0.4-1",
01439         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01440     N_("file name(s) stored as (dirName,baseName,dirIndex) tuple, not as path.")},
01441 #if defined(WITH_BZIP2)
01442     { "rpmlib(PayloadIsBzip2)",         "3.0.5-1",
01443         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01444     N_("package payload can be compressed using bzip2.") },
01445 #endif
01446     { "rpmlib(PayloadFilesHavePrefix)", "4.0-1",
01447         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01448     N_("package payload file(s) have \"./\" prefix.") },
01449     { "rpmlib(ExplicitPackageProvide)", "4.0-1",
01450         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01451     N_("package name-version-release is not implicitly provided.") },
01452     { "rpmlib(HeaderLoadSortsTags)",    "4.0.1-1",
01453         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01454     N_("header tags are always sorted after being loaded.") },
01455     { "rpmlib(ScriptletInterpreterArgs)",    "4.0.3-1",
01456         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01457     N_("the scriptlet interpreter can use arguments from header.") },
01458     { "rpmlib(PartialHardlinkSets)",    "4.0.4-1",
01459         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01460     N_("a hardlink file set may be installed without being complete.") },
01461     { "rpmlib(ConcurrentAccess)",       "4.1-1",
01462         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01463     N_("package scriptlets may access the rpm database while installing.") },
01464 #if defined(WITH_LUA)
01465     { "rpmlib(BuiltinLuaScripts)",      "4.2.2-1",
01466         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01467     N_("internal embedded lua scripts.") },
01468 #endif
01469 #if defined(WITH_AUGEAS)
01470     { "rpmlib(BuiltinAugeasScripts)",   "5.3-1",
01471         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01472     N_("internal embedded Augeas.") },
01473 #endif
01474 #if defined(WITH_FICL)
01475     { "rpmlib(BuiltinFiclScripts)",     "5.2-1",
01476         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01477     N_("internal embedded FICL.") },
01478 #endif
01479 #if defined(WITH_GPSEE)
01480     { "rpmlib(BuiltinJavaScript)",      "5.2-1",
01481         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01482     N_("internal embedded JavaScript.") },
01483 #endif
01484 #if defined(WITH_PERLEMBED)
01485     { "rpmlib(BuiltinPerlScripts)",     "5.2-1",
01486         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01487     N_("internal embedded perl scripts.") },
01488 #endif
01489 #if defined(WITH_PYTHONEMBED)
01490     { "rpmlib(BuiltinPythonScripts)",   "5.2-1",
01491         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01492     N_("internal embedded python scripts.") },
01493 #endif
01494 #if defined(WITH_RUBYEMBED)
01495     { "rpmlib(BuiltinRubyScripts)",     "5.2-1",
01496         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01497     N_("internal embedded ruby scripts.") },
01498 #endif
01499 #if defined(WITH_SEMANAGE)
01500     { "rpmlib(BuiltinSpookScripts)",    "5.3-1",
01501         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01502     N_("internal embedded Spook scripts.") },
01503 #endif
01504 #if defined(WITH_SQLITE)
01505     { "rpmlib(BuiltinSqlScripts)",      "5.3-1",
01506         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01507     N_("internal embedded sqlite3 scripts.") },
01508 #endif
01509 #if defined(WITH_SQUIRREL)
01510     { "rpmlib(BuiltinSquirrelScripts)", "5.2-1",
01511         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01512     N_("internal embedded squirrel scripts.") },
01513 #endif
01514 #if defined(WITH_TCL)
01515     { "rpmlib(BuiltinTclScripts)",      "5.2-1",
01516         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01517     N_("internal embedded tcl scripts.") },
01518 #endif
01519     { "rpmlib(HeaderTagTypeInt64)",     "4.4.3-1",
01520         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01521     N_("header tag data can be of type uint64_t.") },
01522     { "rpmlib(PayloadIsUstar)",         "4.4.4-1",
01523         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01524     N_("package payload can be in ustar tar archive format.") },
01525 #if defined(WITH_XZ)    /* XXX should be 4.4.6, but use SuSE's 4.4.2 instead */
01526     { "rpmlib(PayloadIsLzma)",          "4.4.2-1",
01527         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01528     N_("package payload can be compressed using lzma.") },
01529 #endif
01530     { "rpmlib(FileDigestParameterized)",    "4.4.6-1",
01531         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01532     N_("file digests can be other than MD5.") },
01533     { "rpmlib(FileDigests)",    "4.6.0-1",
01534         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01535     N_("file digests can be other than MD5.") },
01536 #if defined(SUPPORT_AR_PAYLOADS)
01537     { "rpmlib(PayloadIsAr)",            "5.1-1",
01538         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01539     N_("package payload can be in ar archive format.") },
01540 #endif
01541 #if defined(WITH_XZ)
01542     { "rpmlib(PayloadIsXz)",            "5.2-1",
01543         (RPMSENSE_RPMLIB|RPMSENSE_EQUAL),
01544     N_("package payload can be compressed using xz.") },
01545 #endif
01546     { NULL,                             NULL, 0,        NULL }
01547 };
01548 
01555 int rpmdsRpmlib(rpmds * dsp, void * tblp)
01556 {
01557     const struct rpmlibProvides_s * rltblp = tblp;
01558     const struct rpmlibProvides_s * rlp;
01559     int xx;
01560 
01561     if (rltblp == NULL)
01562         rltblp = rpmlibProvides;
01563 
01564     for (rlp = rltblp; rlp->featureName != NULL; rlp++) {
01565         rpmds ds = rpmdsSingle(RPMTAG_PROVIDENAME, rlp->featureName,
01566                         rlp->featureEVR, rlp->featureFlags);
01567         xx = rpmdsMerge(dsp, ds);
01568         (void)rpmdsFree(ds);
01569         ds = NULL;
01570     }
01571     return 0;
01572 }
01573 
01581 static int rpmdsSysinfoFile(rpmPRCO PRCO, const char * fn, int tagN)
01582         /*@globals h_errno, fileSystem, internalState @*/
01583         /*@modifies PRCO, fileSystem, internalState @*/
01584 {
01585     char buf[BUFSIZ];
01586     const char *N, *EVR;
01587     evrFlags Flags;
01588     rpmds ds;
01589     char * f, * fe;
01590     char * g, * ge;
01591     FD_t fd = NULL;
01592     FILE * fp;
01593     int rc = -1;
01594     int ln;
01595     int xx;
01596 
01597     /* XXX for now, collect Dirnames/Filelinktos in Providename */
01598     if (tagN == RPMTAG_DIRNAMES || tagN == RPMTAG_FILELINKTOS)
01599         tagN = RPMTAG_PROVIDENAME;
01600 
01601 assert(fn != NULL);
01602     fd = Fopen(fn, "r.fpio");
01603     if (fd == NULL || Ferror(fd))
01604         goto exit;
01605     fp = fdGetFILE(fd);
01606 
01607     ln = 0;
01608     if (fp != NULL)
01609     while((f = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
01610         ln++;
01611 
01612         /* insure a terminator. */
01613         buf[sizeof(buf)-1] = '\0';
01614 
01615         /* ltrim on line. */
01616         while (*f && _isspace(*f))
01617             f++;
01618 
01619         /* XXX skip YAML "- " markup */
01620         if (f[0] == '-' && _isspace(f[1])) {
01621             f += sizeof("- ")-1;
01622             while (*f && _isspace(*f))
01623                 f++;
01624         }
01625 
01626         /* skip empty lines and comments */
01627         if (*f == '\0' || *f == '#')
01628             continue;
01629 
01630         /* rtrim on line. */
01631         fe = f + strlen(f);
01632         while (--fe > f && _isspace(*fe))
01633             *fe = '\0';
01634 
01635         if (!(xisalnum(f[0]) || strchr("/_%!", f[0]) != NULL)) {
01636             fprintf(stderr, _("%s:%d \"%s\" has invalid name. Skipping ...\n"),
01637                     fn, ln, f);
01638             continue;
01639         }
01640 
01641         /* split on ' '  or comparison operator. */
01642         fe = f;
01643         if (*f == '!') fe++;
01644         while (*fe && !_isspace(*fe) && strchr("!<=>", *fe) == NULL)
01645             fe++;
01646         while (*fe && _isspace(*fe))
01647             *fe++ = '\0';
01648 
01649         N = f;
01650         EVR = NULL;
01651         Flags = 0;
01652 
01653         /* parse for non-path, versioned dependency. */
01654         if (*f != '/' && *fe != '\0') {
01655             /* parse comparison operator */
01656             g = fe;
01657             Flags = rpmEVRflags(fe, (const char **)&g);
01658             if (Flags == 0) {
01659                 fprintf(stderr, _("%s:%d \"%s\" has no comparison operator. Skipping ...\n"),
01660                         fn, ln, fe);
01661                 continue;
01662             }
01663             *fe = '\0';
01664 
01665             /* ltrim on field 2. */
01666             while (*g && _isspace(*g))
01667                 g++;
01668             if (*g == '\0') {
01669                 /* XXX No EVR comparison value found. */
01670                 fprintf(stderr, _("%s:%d \"%s\" has no EVR string. Skipping ...\n"),
01671                         fn, ln, f);
01672                 continue;
01673             }
01674 
01675             ge = g + 1;
01676             while (*ge && !_isspace(*ge))
01677                 ge++;
01678 
01679             if (*ge != '\0')
01680                 *ge = '\0';     /* XXX can't happen, line rtrim'ed already. */
01681 
01682             EVR = g;
01683         }
01684 
01685         if (EVR == NULL)
01686             EVR = "";
01687         Flags |= RPMSENSE_PROBE;
01688         ds = rpmdsSingle(tagN, N, EVR , Flags);
01689         if (ds) {       /* XXX can't happen */
01690             xx = rpmdsMergePRCO(PRCO, ds);
01691             (void)rpmdsFree(ds);
01692             ds = NULL;
01693         }
01694     }
01695     rc = 0;
01696 
01697 exit:
01698     if (fd != NULL) (void) Fclose(fd);
01699     return rc;
01700 }
01701 
01702 #if defined(RPM_VENDOR_WINDRIVER)
01703 #define _ETC_RPM_SYSINFO        "%{_etcrpm}/sysinfo"
01704 #else
01705 #define _ETC_RPM_SYSINFO        SYSCONFIGDIR "/sysinfo"
01706 #endif
01707 
01708 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
01709 const char *_sysinfo_path = NULL;
01710 
01711 /*@-nullassign@*/
01712 /*@unchecked@*/ /*@observer@*/ /*@relnull@*/
01713 static const char *_sysinfo_tags[] = {
01714     "Providename",
01715     "Requirename",
01716     "Conflictname",
01717     "Obsoletename",
01718     "Dirnames",
01719     "Filelinktos",
01720     NULL
01721 };
01722 /*@=nullassign@*/
01723 
01724 int rpmdsSysinfo(rpmPRCO PRCO, const char * fn)
01725         /*@globals _sysinfo_path @*/
01726         /*@modifies _sysinfo_path @*/
01727 {
01728     struct stat * st = memset(alloca(sizeof(*st)), 0, sizeof(*st));
01729     int rc = -1;
01730     int xx;
01731 
01732 /*@-modobserver@*/
01733     if (_sysinfo_path == NULL) {
01734         _sysinfo_path = rpmExpand("%{?_rpmds_sysinfo_path}", NULL);
01735         /* XXX may need to validate path existence somewhen. */
01736         if (!(_sysinfo_path != NULL && *_sysinfo_path == '/')) {
01737 /*@-observertrans @*/
01738             _sysinfo_path = _free(_sysinfo_path);
01739 /*@=observertrans @*/
01740             _sysinfo_path = xstrdup(_ETC_RPM_SYSINFO);
01741         }
01742     }
01743 /*@=modobserver@*/
01744 
01745     if (fn == NULL)
01746         fn = _sysinfo_path;
01747 
01748     if (fn == NULL)
01749         goto exit;
01750 
01751     xx = Stat(fn, st);
01752     if (xx < 0)
01753         goto exit;
01754 
01755     if (S_ISDIR(st->st_mode)) {
01756         const char *dn = fn;
01757         const char **av;
01758         int tagN;
01759         rc = 0;         /* assume success */
01760         for (av = _sysinfo_tags; av && *av; av++) {
01761             tagN = tagValue(*av);
01762             if (tagN < 0)
01763                 continue;
01764             fn = rpmGetPath(dn, "/", *av, NULL);
01765             st = memset(st, 0, sizeof(*st));
01766             xx = Stat(fn, st);
01767             if (xx == 0 && S_ISREG(st->st_mode))
01768                 rc = rpmdsSysinfoFile(PRCO, fn, tagN);
01769             fn = _free(fn);
01770             if (rc)
01771                 break;
01772         }
01773     } else
01774     /* XXX for now, collect Dirnames/Filelinktos in Providename */
01775     if (S_ISREG(st->st_mode))
01776         rc = rpmdsSysinfoFile(PRCO, fn, RPMTAG_PROVIDENAME);
01777 
01778 exit:
01779     return rc;
01780 }
01781 
01782 struct conf {
01783 /*@observer@*/ /*@relnull@*/
01784     const char *name;
01785     const int call_name;
01786     const enum { SYSCONF, CONFSTR, PATHCONF } call;
01787 };
01788 
01789 /*@unchecked@*/ /*@observer@*/
01790 static const struct conf vars[] = {
01791 #ifdef _PC_LINK_MAX
01792     { "LINK_MAX", _PC_LINK_MAX, PATHCONF },
01793 #endif
01794 #ifdef _PC_LINK_MAX
01795     { "_POSIX_LINK_MAX", _PC_LINK_MAX, PATHCONF },
01796 #endif
01797 #ifdef _PC_MAX_CANON
01798     { "MAX_CANON", _PC_MAX_CANON, PATHCONF },
01799 #endif
01800 #ifdef _PC_MAX_CANON
01801     { "_POSIX_MAX_CANON", _PC_MAX_CANON, PATHCONF },
01802 #endif
01803 #ifdef _PC_MAX_INPUT
01804     { "MAX_INPUT", _PC_MAX_INPUT, PATHCONF },
01805 #endif
01806 #ifdef _PC_MAX_INPUT
01807     { "_POSIX_MAX_INPUT", _PC_MAX_INPUT, PATHCONF },
01808 #endif
01809 #ifdef _PC_NAME_MAX
01810     { "NAME_MAX", _PC_NAME_MAX, PATHCONF },
01811 #endif
01812 #ifdef _PC_NAME_MAX
01813     { "_POSIX_NAME_MAX", _PC_NAME_MAX, PATHCONF },
01814 #endif
01815 #ifdef _PC_PATH_MAX
01816     { "PATH_MAX", _PC_PATH_MAX, PATHCONF },
01817 #endif
01818 #ifdef _PC_PATH_MAX
01819     { "_POSIX_PATH_MAX", _PC_PATH_MAX, PATHCONF },
01820 #endif
01821 #ifdef _PC_PIPE_BUF
01822     { "PIPE_BUF", _PC_PIPE_BUF, PATHCONF },
01823 #endif
01824 #ifdef _PC_PIPE_BUF
01825     { "_POSIX_PIPE_BUF", _PC_PIPE_BUF, PATHCONF },
01826 #endif
01827 #ifdef _PC_SOCK_MAXBUF
01828     { "SOCK_MAXBUF", _PC_SOCK_MAXBUF, PATHCONF },
01829 #endif
01830 #ifdef _PC_ASYNC_IO
01831     { "_POSIX_ASYNC_IO", _PC_ASYNC_IO, PATHCONF },
01832 #endif
01833 #ifdef _PC_CHOWN_RESTRICTED
01834     { "_POSIX_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED, PATHCONF },
01835 #endif
01836 #ifdef _PC_NO_TRUNC
01837     { "_POSIX_NO_TRUNC", _PC_NO_TRUNC, PATHCONF },
01838 #endif
01839 #ifdef _PC_PRIO_IO
01840     { "_POSIX_PRIO_IO", _PC_PRIO_IO, PATHCONF },
01841 #endif
01842 #ifdef _PC_SYNC_IO
01843     { "_POSIX_SYNC_IO", _PC_SYNC_IO, PATHCONF },
01844 #endif
01845 #ifdef _PC_VDISABLE
01846     { "_POSIX_VDISABLE", _PC_VDISABLE, PATHCONF },
01847 #endif
01848 
01849 #ifdef _SC_ARG_MAX
01850     { "ARG_MAX", _SC_ARG_MAX, SYSCONF },
01851 #endif
01852 #ifdef _SC_ATEXIT_MAX
01853     { "ATEXIT_MAX", _SC_ATEXIT_MAX, SYSCONF },
01854 #endif
01855 #ifdef _SC_CHAR_BIT
01856     { "CHAR_BIT", _SC_CHAR_BIT, SYSCONF },
01857 #endif
01858 #ifdef _SC_CHAR_MAX
01859     { "CHAR_MAX", _SC_CHAR_MAX, SYSCONF },
01860 #endif
01861 #ifdef _SC_CHAR_MIN
01862     { "CHAR_MIN", _SC_CHAR_MIN, SYSCONF },
01863 #endif
01864 #ifdef _SC_CHILD_MAX
01865     { "CHILD_MAX", _SC_CHILD_MAX, SYSCONF },
01866 #endif
01867 #ifdef _SC_CLK_TCK
01868     { "CLK_TCK", _SC_CLK_TCK, SYSCONF },
01869 #endif
01870 #ifdef _SC_INT_MAX
01871     { "INT_MAX", _SC_INT_MAX, SYSCONF },
01872 #endif
01873 #ifdef _SC_INT_MIN
01874     { "INT_MIN", _SC_INT_MIN, SYSCONF },
01875 #endif
01876 #ifdef _SC_UIO_MAXIOV
01877     { "IOV_MAX", _SC_UIO_MAXIOV, SYSCONF },
01878 #endif
01879 #ifdef _SC_LOGIN_NAME_MAX
01880     { "LOGNAME_MAX", _SC_LOGIN_NAME_MAX, SYSCONF },
01881 #endif
01882 #ifdef _SC_LONG_BIT
01883     { "LONG_BIT", _SC_LONG_BIT, SYSCONF },
01884 #endif
01885 #ifdef _SC_MB_LEN_MAX
01886     { "MB_LEN_MAX", _SC_MB_LEN_MAX, SYSCONF },
01887 #endif
01888 #ifdef _SC_NGROUPS_MAX
01889     { "NGROUPS_MAX", _SC_NGROUPS_MAX, SYSCONF },
01890 #endif
01891 #ifdef _SC_NL_ARGMAX
01892     { "NL_ARGMAX", _SC_NL_ARGMAX, SYSCONF },
01893 #endif
01894 #ifdef _SC_NL_LANGMAX
01895     { "NL_LANGMAX", _SC_NL_LANGMAX, SYSCONF },
01896 #endif
01897 #ifdef _SC_NL_MSGMAX
01898     { "NL_MSGMAX", _SC_NL_MSGMAX, SYSCONF },
01899 #endif
01900 #ifdef _SC_NL_NMAX
01901     { "NL_NMAX", _SC_NL_NMAX, SYSCONF },
01902 #endif
01903 #ifdef _SC_NL_SETMAX
01904     { "NL_SETMAX", _SC_NL_SETMAX, SYSCONF },
01905 #endif
01906 #ifdef _SC_NL_TEXTMAX
01907     { "NL_TEXTMAX", _SC_NL_TEXTMAX, SYSCONF },
01908 #endif
01909 #ifdef _SC_GETGR_R_SIZE_MAX
01910     { "NSS_BUFLEN_GROUP", _SC_GETGR_R_SIZE_MAX, SYSCONF },
01911 #endif
01912 #ifdef _SC_GETPW_R_SIZE_MAX
01913     { "NSS_BUFLEN_PASSWD", _SC_GETPW_R_SIZE_MAX, SYSCONF },
01914 #endif
01915 #ifdef _SC_NZERO
01916     { "NZERO", _SC_NZERO, SYSCONF },
01917 #endif
01918 #ifdef _SC_OPEN_MAX
01919     { "OPEN_MAX", _SC_OPEN_MAX, SYSCONF },
01920 #endif
01921 #ifdef _SC_PAGESIZE
01922     { "PAGESIZE", _SC_PAGESIZE, SYSCONF },
01923 #endif
01924 #ifdef _SC_PAGESIZE
01925     { "PAGE_SIZE", _SC_PAGESIZE, SYSCONF },
01926 #endif
01927 #ifdef _SC_PASS_MAX
01928     { "PASS_MAX", _SC_PASS_MAX, SYSCONF },
01929 #endif
01930 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
01931     { "PTHREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS, SYSCONF },
01932 #endif
01933 #ifdef _SC_THREAD_KEYS_MAX
01934     { "PTHREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX, SYSCONF },
01935 #endif
01936 #ifdef _SC_THREAD_STACK_MIN
01937     { "PTHREAD_STACK_MIN", _SC_THREAD_STACK_MIN, SYSCONF },
01938 #endif
01939 #ifdef _SC_THREAD_THREADS_MAX
01940     { "PTHREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX, SYSCONF },
01941 #endif
01942 #ifdef _SC_SCHAR_MAX
01943     { "SCHAR_MAX", _SC_SCHAR_MAX, SYSCONF },
01944 #endif
01945 #ifdef _SC_SCHAR_MIN
01946     { "SCHAR_MIN", _SC_SCHAR_MIN, SYSCONF },
01947 #endif
01948 #ifdef _SC_SHRT_MAX
01949     { "SHRT_MAX", _SC_SHRT_MAX, SYSCONF },
01950 #endif
01951 #ifdef _SC_SHRT_MIN
01952     { "SHRT_MIN", _SC_SHRT_MIN, SYSCONF },
01953 #endif
01954 #ifdef _SC_SSIZE_MAX
01955     { "SSIZE_MAX", _SC_SSIZE_MAX, SYSCONF },
01956 #endif
01957 #ifdef _SC_TTY_NAME_MAX
01958     { "TTY_NAME_MAX", _SC_TTY_NAME_MAX, SYSCONF },
01959 #endif
01960 #ifdef _SC_TZNAME_MAX
01961     { "TZNAME_MAX", _SC_TZNAME_MAX, SYSCONF },
01962 #endif
01963 #ifdef _SC_UCHAR_MAX
01964     { "UCHAR_MAX", _SC_UCHAR_MAX, SYSCONF },
01965 #endif
01966 #ifdef _SC_UINT_MAX
01967     { "UINT_MAX", _SC_UINT_MAX, SYSCONF },
01968 #endif
01969 #ifdef _SC_UIO_MAXIOV
01970     { "UIO_MAXIOV", _SC_UIO_MAXIOV, SYSCONF },
01971 #endif
01972 #ifdef _SC_ULONG_MAX
01973     { "ULONG_MAX", _SC_ULONG_MAX, SYSCONF },
01974 #endif
01975 #ifdef _SC_USHRT_MAX
01976     { "USHRT_MAX", _SC_USHRT_MAX, SYSCONF },
01977 #endif
01978 #ifdef _SC_WORD_BIT
01979     { "WORD_BIT", _SC_WORD_BIT, SYSCONF },
01980 #endif
01981 #ifdef _SC_AVPHYS_PAGES
01982     { "_AVPHYS_PAGES", _SC_AVPHYS_PAGES, SYSCONF },
01983 #endif
01984 #ifdef _SC_NPROCESSORS_CONF
01985     { "_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF, SYSCONF },
01986 #endif
01987 #ifdef _SC_NPROCESSORS_ONLN
01988     { "_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN, SYSCONF },
01989 #endif
01990 #ifdef _SC_PHYS_PAGES
01991     { "_PHYS_PAGES", _SC_PHYS_PAGES, SYSCONF },
01992 #endif
01993 #ifdef _SC_ARG_MAX
01994     { "_POSIX_ARG_MAX", _SC_ARG_MAX, SYSCONF },
01995 #endif
01996 #ifdef _SC_ASYNCHRONOUS_IO
01997     { "_POSIX_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO, SYSCONF },
01998 #endif
01999 #ifdef _SC_CHILD_MAX
02000     { "_POSIX_CHILD_MAX", _SC_CHILD_MAX, SYSCONF },
02001 #endif
02002 #ifdef _SC_FSYNC
02003     { "_POSIX_FSYNC", _SC_FSYNC, SYSCONF },
02004 #endif
02005 #ifdef _SC_JOB_CONTROL
02006     { "_POSIX_JOB_CONTROL", _SC_JOB_CONTROL, SYSCONF },
02007 #endif
02008 #ifdef _SC_MAPPED_FILES
02009     { "_POSIX_MAPPED_FILES", _SC_MAPPED_FILES, SYSCONF },
02010 #endif
02011 #ifdef _SC_MEMLOCK
02012     { "_POSIX_MEMLOCK", _SC_MEMLOCK, SYSCONF },
02013 #endif
02014 #ifdef _SC_MEMLOCK_RANGE
02015     { "_POSIX_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE, SYSCONF },
02016 #endif
02017 #ifdef _SC_MEMORY_PROTECTION
02018     { "_POSIX_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION, SYSCONF },
02019 #endif
02020 #ifdef _SC_MESSAGE_PASSING
02021     { "_POSIX_MESSAGE_PASSING", _SC_MESSAGE_PASSING, SYSCONF },
02022 #endif
02023 #ifdef _SC_NGROUPS_MAX
02024     { "_POSIX_NGROUPS_MAX", _SC_NGROUPS_MAX, SYSCONF },
02025 #endif
02026 #ifdef _SC_OPEN_MAX
02027     { "_POSIX_OPEN_MAX", _SC_OPEN_MAX, SYSCONF },
02028 #endif
02029 #ifdef _SC_PII
02030     { "_POSIX_PII", _SC_PII, SYSCONF },
02031 #endif
02032 #ifdef _SC_PII_INTERNET
02033     { "_POSIX_PII_INTERNET", _SC_PII_INTERNET, SYSCONF },
02034 #endif
02035 #ifdef _SC_PII_INTERNET_DGRAM
02036     { "_POSIX_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM, SYSCONF },
02037 #endif
02038 #ifdef _SC_PII_INTERNET_STREAM
02039     { "_POSIX_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM, SYSCONF },
02040 #endif
02041 #ifdef _SC_PII_OSI
02042     { "_POSIX_PII_OSI", _SC_PII_OSI, SYSCONF },
02043 #endif
02044 #ifdef _SC_PII_OSI_CLTS
02045     { "_POSIX_PII_OSI_CLTS", _SC_PII_OSI_CLTS, SYSCONF },
02046 #endif
02047 #ifdef _SC_PII_OSI_COTS
02048     { "_POSIX_PII_OSI_COTS", _SC_PII_OSI_COTS, SYSCONF },
02049 #endif
02050 #ifdef _SC_PII_OSI_M
02051     { "_POSIX_PII_OSI_M", _SC_PII_OSI_M, SYSCONF },
02052 #endif
02053 #ifdef _SC_PII_SOCKET
02054     { "_POSIX_PII_SOCKET", _SC_PII_SOCKET, SYSCONF },
02055 #endif
02056 #ifdef _SC_PII_XTI
02057     { "_POSIX_PII_XTI", _SC_PII_XTI, SYSCONF },
02058 #endif
02059 #ifdef _SC_POLL
02060     { "_POSIX_POLL", _SC_POLL, SYSCONF },
02061 #endif
02062 #ifdef _SC_PRIORITIZED_IO
02063     { "_POSIX_PRIORITIZED_IO", _SC_PRIORITIZED_IO, SYSCONF },
02064 #endif
02065 #ifdef _SC_PRIORITY_SCHEDULING
02066     { "_POSIX_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING, SYSCONF },
02067 #endif
02068 #ifdef _SC_REALTIME_SIGNALS
02069     { "_POSIX_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS, SYSCONF },
02070 #endif
02071 #ifdef _SC_SAVED_IDS
02072     { "_POSIX_SAVED_IDS", _SC_SAVED_IDS, SYSCONF },
02073 #endif
02074 #ifdef _SC_SELECT
02075     { "_POSIX_SELECT", _SC_SELECT, SYSCONF },
02076 #endif
02077 #ifdef _SC_SEMAPHORES
02078     { "_POSIX_SEMAPHORES", _SC_SEMAPHORES, SYSCONF },
02079 #endif
02080 #ifdef _SC_SHARED_MEMORY_OBJECTS
02081     { "_POSIX_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS, SYSCONF },
02082 #endif
02083 #ifdef _SC_SSIZE_MAX
02084     { "_POSIX_SSIZE_MAX", _SC_SSIZE_MAX, SYSCONF },
02085 #endif
02086 #ifdef _SC_STREAM_MAX
02087     { "_POSIX_STREAM_MAX", _SC_STREAM_MAX, SYSCONF },
02088 #endif
02089 #ifdef _SC_SYNCHRONIZED_IO
02090     { "_POSIX_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO, SYSCONF },
02091 #endif
02092 #ifdef _SC_THREADS
02093     { "_POSIX_THREADS", _SC_THREADS, SYSCONF },
02094 #endif
02095 #ifdef _SC_THREAD_ATTR_STACKADDR
02096     { "_POSIX_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR, SYSCONF },
02097 #endif
02098 #ifdef _SC_THREAD_ATTR_STACKSIZE
02099     { "_POSIX_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE, SYSCONF },
02100 #endif
02101 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
02102     { "_POSIX_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING, SYSCONF },
02103 #endif
02104 #ifdef _SC_THREAD_PRIO_INHERIT
02105     { "_POSIX_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT, SYSCONF },
02106 #endif
02107 #ifdef _SC_THREAD_PRIO_PROTECT
02108     { "_POSIX_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT, SYSCONF },
02109 #endif
02110 #ifdef _SC_THREAD_PROCESS_SHARED
02111     { "_POSIX_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED, SYSCONF },
02112 #endif
02113 #ifdef _SC_THREAD_SAFE_FUNCTIONS
02114     { "_POSIX_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS, SYSCONF },
02115 #endif
02116 #ifdef _SC_TIMERS
02117     { "_POSIX_TIMERS", _SC_TIMERS, SYSCONF },
02118 #endif
02119 #ifdef _SC_TIMER_MAX
02120     { "TIMER_MAX", _SC_TIMER_MAX, SYSCONF },
02121 #endif
02122 #ifdef _SC_TZNAME_MAX
02123     { "_POSIX_TZNAME_MAX", _SC_TZNAME_MAX, SYSCONF },
02124 #endif
02125 #ifdef _SC_VERSION
02126     { "_POSIX_VERSION", _SC_VERSION, SYSCONF },
02127 #endif
02128 #ifdef _SC_T_IOV_MAX
02129     { "_T_IOV_MAX", _SC_T_IOV_MAX, SYSCONF },
02130 #endif
02131 #ifdef _SC_XOPEN_CRYPT
02132     { "_XOPEN_CRYPT", _SC_XOPEN_CRYPT, SYSCONF },
02133 #endif
02134 #ifdef _SC_XOPEN_ENH_I18N
02135     { "_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N, SYSCONF },
02136 #endif
02137 #ifdef _SC_XOPEN_LEGACY
02138     { "_XOPEN_LEGACY", _SC_XOPEN_LEGACY, SYSCONF },
02139 #endif
02140 #ifdef _SC_XOPEN_REALTIME
02141     { "_XOPEN_REALTIME", _SC_XOPEN_REALTIME, SYSCONF },
02142 #endif
02143 #ifdef _SC_XOPEN_REALTIME_THREADS
02144     { "_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS, SYSCONF },
02145 #endif
02146 #ifdef _SC_XOPEN_SHM
02147     { "_XOPEN_SHM", _SC_XOPEN_SHM, SYSCONF },
02148 #endif
02149 #ifdef _SC_XOPEN_UNIX
02150     { "_XOPEN_UNIX", _SC_XOPEN_UNIX, SYSCONF },
02151 #endif
02152 #ifdef _SC_XOPEN_VERSION
02153     { "_XOPEN_VERSION", _SC_XOPEN_VERSION, SYSCONF },
02154 #endif
02155 #ifdef _SC_XOPEN_XCU_VERSION
02156     { "_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION, SYSCONF },
02157 #endif
02158 #ifdef _SC_XOPEN_XPG2
02159     { "_XOPEN_XPG2", _SC_XOPEN_XPG2, SYSCONF },
02160 #endif
02161 #ifdef _SC_XOPEN_XPG3
02162     { "_XOPEN_XPG3", _SC_XOPEN_XPG3, SYSCONF },
02163 #endif
02164 #ifdef _SC_XOPEN_XPG4
02165     { "_XOPEN_XPG4", _SC_XOPEN_XPG4, SYSCONF },
02166 #endif
02167     /* POSIX.2  */
02168 #ifdef _SC_BC_BASE_MAX
02169     { "BC_BASE_MAX", _SC_BC_BASE_MAX, SYSCONF },
02170 #endif
02171 #ifdef _SC_BC_DIM_MAX
02172     { "BC_DIM_MAX", _SC_BC_DIM_MAX, SYSCONF },
02173 #endif
02174 #ifdef _SC_BC_SCALE_MAX
02175     { "BC_SCALE_MAX", _SC_BC_SCALE_MAX, SYSCONF },
02176 #endif
02177 #ifdef _SC_BC_STRING_MAX
02178     { "BC_STRING_MAX", _SC_BC_STRING_MAX, SYSCONF },
02179 #endif
02180 #ifdef _SC_CHARCLASS_NAME_MAX
02181     { "CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX, SYSCONF },
02182 #endif
02183 #ifdef _SC_COLL_WEIGHTS_MAX
02184     { "COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX, SYSCONF },
02185 #endif
02186 #ifdef _SC_EQUIV_CLASS_MAX
02187     { "EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX, SYSCONF },
02188 #endif
02189 #ifdef _SC_EXPR_NEST_MAX
02190     { "EXPR_NEST_MAX", _SC_EXPR_NEST_MAX, SYSCONF },
02191 #endif
02192 #ifdef _SC_LINE_MAX
02193     { "LINE_MAX", _SC_LINE_MAX, SYSCONF },
02194 #endif
02195 #ifdef _SC_BC_BASE_MAX
02196     { "POSIX2_BC_BASE_MAX", _SC_BC_BASE_MAX, SYSCONF },
02197 #endif
02198 #ifdef _SC_BC_DIM_MAX
02199     { "POSIX2_BC_DIM_MAX", _SC_BC_DIM_MAX, SYSCONF },
02200 #endif
02201 #ifdef _SC_BC_SCALE_MAX
02202     { "POSIX2_BC_SCALE_MAX", _SC_BC_SCALE_MAX, SYSCONF },
02203 #endif
02204 #ifdef _SC_BC_STRING_MAX
02205     { "POSIX2_BC_STRING_MAX", _SC_BC_STRING_MAX, SYSCONF },
02206 #endif
02207 #ifdef _SC_2_CHAR_TERM
02208     { "POSIX2_CHAR_TERM", _SC_2_CHAR_TERM, SYSCONF },
02209 #endif
02210 #ifdef _SC_COLL_WEIGHTS_MAX
02211     { "POSIX2_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX, SYSCONF },
02212 #endif
02213 #ifdef _SC_2_C_BIND
02214     { "POSIX2_C_BIND", _SC_2_C_BIND, SYSCONF },
02215 #endif
02216 #ifdef _SC_2_C_DEV
02217     { "POSIX2_C_DEV", _SC_2_C_DEV, SYSCONF },
02218 #endif
02219 #ifdef _SC_2_C_VERSION
02220     { "POSIX2_C_VERSION", _SC_2_C_VERSION, SYSCONF },
02221 #endif
02222 #ifdef _SC_EXPR_NEST_MAX
02223     { "POSIX2_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX, SYSCONF },
02224 #endif
02225 #ifdef _SC_2_FORT_DEV
02226     { "POSIX2_FORT_DEV", _SC_2_FORT_DEV, SYSCONF },
02227 #endif
02228 #ifdef _SC_2_FORT_RUN
02229     { "POSIX2_FORT_RUN", _SC_2_FORT_RUN, SYSCONF },
02230 #endif
02231 #ifdef _SC_LINE_MAX
02232     { "_POSIX2_LINE_MAX", _SC_LINE_MAX, SYSCONF },
02233 #endif
02234 #ifdef _SC_2_LOCALEDEF
02235     { "POSIX2_LOCALEDEF", _SC_2_LOCALEDEF, SYSCONF },
02236 #endif
02237 #ifdef _SC_RE_DUP_MAX
02238     { "POSIX2_RE_DUP_MAX", _SC_RE_DUP_MAX, SYSCONF },
02239 #endif
02240 #ifdef _SC_2_SW_DEV
02241     { "POSIX2_SW_DEV", _SC_2_SW_DEV, SYSCONF },
02242 #endif
02243 #ifdef _SC_2_UPE
02244     { "POSIX2_UPE", _SC_2_UPE, SYSCONF },
02245 #endif
02246 #ifdef _SC_2_VERSION
02247     { "POSIX2_VERSION", _SC_2_VERSION, SYSCONF },
02248 #endif
02249 #ifdef _SC_RE_DUP_MAX
02250     { "RE_DUP_MAX", _SC_RE_DUP_MAX, SYSCONF },
02251 #endif
02252 
02253 #ifdef _CS_PATH
02254     { "PATH", _CS_PATH, CONFSTR },
02255     { "CS_PATH", _CS_PATH, CONFSTR },
02256 #endif
02257 
02258     /* LFS */
02259 #ifdef _CS_LFS_CFLAGS
02260     { "LFS_CFLAGS", _CS_LFS_CFLAGS, CONFSTR },
02261 #endif
02262 #ifdef _CS_LFS_LDFLAGS
02263     { "LFS_LDFLAGS", _CS_LFS_LDFLAGS, CONFSTR },
02264 #endif
02265 #ifdef _CS_LFS_LIBS
02266     { "LFS_LIBS", _CS_LFS_LIBS, CONFSTR },
02267 #endif
02268 #ifdef _CS_LFS_LINTFLAGS
02269     { "LFS_LINTFLAGS", _CS_LFS_LINTFLAGS, CONFSTR },
02270 #endif
02271 #ifdef _CS_LFS64_CFLAGS
02272     { "LFS64_CFLAGS", _CS_LFS64_CFLAGS, CONFSTR },
02273 #endif
02274 #ifdef _CS_LFS64_LDFLAGS
02275     { "LFS64_LDFLAGS", _CS_LFS64_LDFLAGS, CONFSTR },
02276 #endif
02277 #ifdef _CS_LFS64_LIBS
02278     { "LFS64_LIBS", _CS_LFS64_LIBS, CONFSTR },
02279 #endif
02280 #ifdef _CS_LFS64_LINTFLAGS
02281     { "LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS, CONFSTR },
02282 #endif
02283 
02284     /* Programming environments.  */
02285 #ifdef _SC_XBS5_ILP32_OFF32
02286     { "_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32, SYSCONF },
02287 #endif
02288 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
02289     { "XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS, CONFSTR },
02290 #endif
02291 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
02292     { "XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS, CONFSTR },
02293 #endif
02294 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
02295     { "XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS, CONFSTR },
02296 #endif
02297 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
02298     { "XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS, CONFSTR },
02299 #endif
02300 
02301 #ifdef _SC_XBS5_ILP32_OFFBIG
02302     { "_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG, SYSCONF },
02303 #endif
02304 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
02305     { "XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS, CONFSTR },
02306 #endif
02307 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
02308     { "XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS, CONFSTR },
02309 #endif
02310 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
02311     { "XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS, CONFSTR },
02312 #endif
02313 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
02314     { "XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS, CONFSTR },
02315 #endif
02316 
02317 #ifdef _SC_XBS5_LP64_OFF64
02318     { "_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64, SYSCONF },
02319 #endif
02320 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
02321     { "XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS, CONFSTR },
02322 #endif
02323 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
02324     { "XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS, CONFSTR },
02325 #endif
02326 #ifdef _CS_XBS5_LP64_OFF64_LIBS
02327     { "XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS, CONFSTR },
02328 #endif
02329 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
02330     { "XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS, CONFSTR },
02331 #endif
02332 
02333 #ifdef _SC_XBS5_LPBIG_OFFBIG
02334     { "_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG, SYSCONF },
02335 #endif
02336 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
02337     { "XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS, CONFSTR },
02338 #endif
02339 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
02340     { "XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS, CONFSTR },
02341 #endif
02342 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
02343     { "XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS, CONFSTR },
02344 #endif
02345 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
02346     { "XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS, CONFSTR },
02347 #endif
02348 
02349 #ifdef _SC_V6_ILP32_OFF32
02350     { "_POSIX_V6_ILP32_OFF32", _SC_V6_ILP32_OFF32, SYSCONF },
02351 #endif
02352 #ifdef _CS_POSIX_V6_ILP32_OFF32_CFLAGS
02353     { "POSIX_V6_ILP32_OFF32_CFLAGS", _CS_POSIX_V6_ILP32_OFF32_CFLAGS, CONFSTR },
02354 #endif
02355 #ifdef _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
02356     { "POSIX_V6_ILP32_OFF32_LDFLAGS", _CS_POSIX_V6_ILP32_OFF32_LDFLAGS, CONFSTR },
02357 #endif
02358 #ifdef _CS_POSIX_V6_ILP32_OFF32_LIBS
02359     { "POSIX_V6_ILP32_OFF32_LIBS", _CS_POSIX_V6_ILP32_OFF32_LIBS, CONFSTR },
02360 #endif
02361 #ifdef _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS
02362     { "POSIX_V6_ILP32_OFF32_LINTFLAGS", _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS, CONFSTR },
02363 #endif
02364 
02365 #ifdef _CS_V6_WIDTH_RESTRICTED_ENVS
02366     { "_POSIX_V6_WIDTH_RESTRICTED_ENVS", _CS_V6_WIDTH_RESTRICTED_ENVS, CONFSTR },
02367 #endif
02368 
02369 #ifdef _SC_V6_ILP32_OFFBIG
02370     { "_POSIX_V6_ILP32_OFFBIG", _SC_V6_ILP32_OFFBIG, SYSCONF },
02371 #endif
02372 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
02373     { "POSIX_V6_ILP32_OFFBIG_CFLAGS", _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS, CONFSTR },
02374 #endif
02375 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
02376     { "POSIX_V6_ILP32_OFFBIG_LDFLAGS", _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS, CONFSTR },
02377 #endif
02378 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_LIBS
02379     { "POSIX_V6_ILP32_OFFBIG_LIBS", _CS_POSIX_V6_ILP32_OFFBIG_LIBS, CONFSTR },
02380 #endif
02381 #ifdef _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS
02382     { "POSIX_V6_ILP32_OFFBIG_LINTFLAGS", _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS, CONFSTR },
02383 #endif
02384 
02385 #ifdef _SC_V6_LP64_OFF64
02386     { "_POSIX_V6_LP64_OFF64", _SC_V6_LP64_OFF64, SYSCONF },
02387 #endif
02388 #ifdef _CS_POSIX_V6_LP64_OFF64_CFLAGS
02389     { "POSIX_V6_LP64_OFF64_CFLAGS", _CS_POSIX_V6_LP64_OFF64_CFLAGS, CONFSTR },
02390 #endif
02391 #ifdef _CS_POSIX_V6_LP64_OFF64_LDFLAGS
02392     { "POSIX_V6_LP64_OFF64_LDFLAGS", _CS_POSIX_V6_LP64_OFF64_LDFLAGS, CONFSTR },
02393 #endif
02394 #ifdef _CS_POSIX_V6_LP64_OFF64_LIBS
02395     { "POSIX_V6_LP64_OFF64_LIBS", _CS_POSIX_V6_LP64_OFF64_LIBS, CONFSTR },
02396 #endif
02397 #ifdef _CS_POSIX_V6_LP64_OFF64_LINTFLAGS
02398     { "POSIX_V6_LP64_OFF64_LINTFLAGS", _CS_POSIX_V6_LP64_OFF64_LINTFLAGS, CONFSTR },
02399 #endif
02400 
02401 #ifdef _SC_V6_LPBIG_OFFBIG
02402     { "_POSIX_V6_LPBIG_OFFBIG", _SC_V6_LPBIG_OFFBIG, SYSCONF },
02403 #endif
02404 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
02405     { "POSIX_V6_LPBIG_OFFBIG_CFLAGS", _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS, CONFSTR },
02406 #endif
02407 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
02408     { "POSIX_V6_LPBIG_OFFBIG_LDFLAGS", _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS, CONFSTR },
02409 #endif
02410 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
02411     { "POSIX_V6_LPBIG_OFFBIG_LIBS", _CS_POSIX_V6_LPBIG_OFFBIG_LIBS, CONFSTR },
02412 #endif
02413 #ifdef _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
02414     { "POSIX_V6_LPBIG_OFFBIG_LINTFLAGS", _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS, CONFSTR },
02415 #endif
02416 
02417 #ifdef _SC_ADVISORY_INFO
02418     { "_POSIX_ADVISORY_INFO", _SC_ADVISORY_INFO, SYSCONF },
02419 #endif
02420 #ifdef _SC_BARRIERS
02421     { "_POSIX_BARRIERS", _SC_BARRIERS, SYSCONF },
02422 #endif
02423 #ifdef _SC_BASE
02424     { "_POSIX_BASE", _SC_BASE, SYSCONF },
02425 #endif
02426 #ifdef _SC_C_LANG_SUPPORT
02427     { "_POSIX_C_LANG_SUPPORT", _SC_C_LANG_SUPPORT, SYSCONF },
02428 #endif
02429 #ifdef _SC_C_LANG_SUPPORT_R
02430     { "_POSIX_C_LANG_SUPPORT_R", _SC_C_LANG_SUPPORT_R, SYSCONF },
02431 #endif
02432 #ifdef _SC_CLOCK_SELECTION
02433     { "_POSIX_CLOCK_SELECTION", _SC_CLOCK_SELECTION, SYSCONF },
02434 #endif
02435 #ifdef _SC_CPUTIME
02436     { "_POSIX_CPUTIME", _SC_CPUTIME, SYSCONF },
02437 #endif
02438 #ifdef _SC_THREAD_CPUTIME
02439     { "_POSIX_THREAD_CPUTIME", _SC_THREAD_CPUTIME, SYSCONF },
02440 #endif
02441 #ifdef _SC_DEVICE_SPECIFIC
02442     { "_POSIX_DEVICE_SPECIFIC", _SC_DEVICE_SPECIFIC, SYSCONF },
02443 #endif
02444 #ifdef _SC_DEVICE_SPECIFIC_R
02445     { "_POSIX_DEVICE_SPECIFIC_R", _SC_DEVICE_SPECIFIC_R, SYSCONF },
02446 #endif
02447 #ifdef _SC_FD_MGMT
02448     { "_POSIX_FD_MGMT", _SC_FD_MGMT, SYSCONF },
02449 #endif
02450 #ifdef _SC_FIFO
02451     { "_POSIX_FIFO", _SC_FIFO, SYSCONF },
02452 #endif
02453 #ifdef _SC_PIPE
02454     { "_POSIX_PIPE", _SC_PIPE, SYSCONF },
02455 #endif
02456 #ifdef _SC_FILE_ATTRIBUTES
02457     { "_POSIX_FILE_ATTRIBUTES", _SC_FILE_ATTRIBUTES, SYSCONF },
02458 #endif
02459 #ifdef _SC_FILE_LOCKING
02460     { "_POSIX_FILE_LOCKING", _SC_FILE_LOCKING, SYSCONF },
02461 #endif
02462 #ifdef _SC_FILE_SYSTEM
02463     { "_POSIX_FILE_SYSTEM", _SC_FILE_SYSTEM, SYSCONF },
02464 #endif
02465 #ifdef _SC_MONOTONIC_CLOCK
02466     { "_POSIX_MONOTONIC_CLOCK", _SC_MONOTONIC_CLOCK, SYSCONF },
02467 #endif
02468 #ifdef _SC_MULTI_PROCESS
02469     { "_POSIX_MULTI_PROCESS", _SC_MULTI_PROCESS, SYSCONF },
02470 #endif
02471 #ifdef _SC_SINGLE_PROCESS
02472     { "_POSIX_SINGLE_PROCESS", _SC_SINGLE_PROCESS, SYSCONF },
02473 #endif
02474 #ifdef _SC_NETWORKING
02475     { "_POSIX_NETWORKING", _SC_NETWORKING, SYSCONF },
02476 #endif
02477 #ifdef _SC_READER_WRITER_LOCKS
02478     { "_POSIX_READER_WRITER_LOCKS", _SC_READER_WRITER_LOCKS, SYSCONF },
02479 #endif
02480 #ifdef _SC_SPIN_LOCKS
02481     { "_POSIX_SPIN_LOCKS", _SC_SPIN_LOCKS, SYSCONF },
02482 #endif
02483 #ifdef _SC_REGEXP
02484     { "_POSIX_REGEXP", _SC_REGEXP, SYSCONF },
02485 #endif
02486 #ifdef _SC_REGEX_VERSION
02487     { "_REGEX_VERSION", _SC_REGEX_VERSION, SYSCONF },
02488 #endif
02489 #ifdef _SC_SHELL
02490     { "_POSIX_SHELL", _SC_SHELL, SYSCONF },
02491 #endif
02492 #ifdef _SC_SIGNALS
02493     { "_POSIX_SIGNALS", _SC_SIGNALS, SYSCONF },
02494 #endif
02495 #ifdef _SC_SPAWN
02496     { "_POSIX_SPAWN", _SC_SPAWN, SYSCONF },
02497 #endif
02498 #ifdef _SC_SPORADIC_SERVER
02499     { "_POSIX_SPORADIC_SERVER", _SC_SPORADIC_SERVER, SYSCONF },
02500 #endif
02501 #ifdef _SC_THREAD_SPORADIC_SERVER
02502     { "_POSIX_THREAD_SPORADIC_SERVER", _SC_THREAD_SPORADIC_SERVER, SYSCONF },
02503 #endif
02504 #ifdef _SC_SYSTEM_DATABASE
02505     { "_POSIX_SYSTEM_DATABASE", _SC_SYSTEM_DATABASE, SYSCONF },
02506 #endif
02507 #ifdef _SC_SYSTEM_DATABASE_R
02508     { "_POSIX_SYSTEM_DATABASE_R", _SC_SYSTEM_DATABASE_R, SYSCONF },
02509 #endif
02510 #ifdef _SC_TIMEOUTS
02511     { "_POSIX_TIMEOUTS", _SC_TIMEOUTS, SYSCONF },
02512 #endif
02513 #ifdef _SC_TYPED_MEMORY_OBJECTS
02514     { "_POSIX_TYPED_MEMORY_OBJECTS", _SC_TYPED_MEMORY_OBJECTS, SYSCONF },
02515 #endif
02516 #ifdef _SC_USER_GROUPS
02517     { "_POSIX_USER_GROUPS", _SC_USER_GROUPS, SYSCONF },
02518 #endif
02519 #ifdef _SC_USER_GROUPS_R
02520     { "_POSIX_USER_GROUPS_R", _SC_USER_GROUPS_R, SYSCONF },
02521 #endif
02522 #ifdef _SC_2_PBS
02523     { "POSIX2_PBS", _SC_2_PBS, SYSCONF },
02524 #endif
02525 #ifdef _SC_2_PBS_ACCOUNTING
02526     { "POSIX2_PBS_ACCOUNTING", _SC_2_PBS_ACCOUNTING, SYSCONF },
02527 #endif
02528 #ifdef _SC_2_PBS_LOCATE
02529     { "POSIX2_PBS_LOCATE", _SC_2_PBS_LOCATE, SYSCONF },
02530 #endif
02531 #ifdef _SC_2_PBS_TRACK
02532     { "POSIX2_PBS_TRACK", _SC_2_PBS_TRACK, SYSCONF },
02533 #endif
02534 #ifdef _SC_2_PBS_MESSAGE
02535     { "POSIX2_PBS_MESSAGE", _SC_2_PBS_MESSAGE, SYSCONF },
02536 #endif
02537 #ifdef _SC_SYMLOOP_MAX
02538     { "SYMLOOP_MAX", _SC_SYMLOOP_MAX, SYSCONF },
02539 #endif
02540 #ifdef _SC_STREAM_MAX
02541     { "STREAM_MAX", _SC_STREAM_MAX, SYSCONF },
02542 #endif
02543 #ifdef _SC_AIO_LISTIO_MAX
02544     { "AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX, SYSCONF },
02545 #endif
02546 #ifdef _SC_AIO_MAX
02547     { "AIO_MAX", _SC_AIO_MAX, SYSCONF },
02548 #endif
02549 #ifdef _SC_AIO_PRIO_DELTA_MAX
02550     { "AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX, SYSCONF },
02551 #endif
02552 #ifdef _SC_DELAYTIMER_MAX
02553     { "DELAYTIMER_MAX", _SC_DELAYTIMER_MAX, SYSCONF },
02554 #endif
02555 #ifdef _SC_HOST_NAME_MAX
02556     { "HOST_NAME_MAX", _SC_HOST_NAME_MAX, SYSCONF },
02557 #endif
02558 #ifdef _SC_LOGIN_NAME_MAX
02559     { "LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX, SYSCONF },
02560 #endif
02561 #ifdef _SC_MQ_OPEN_MAX
02562     { "MQ_OPEN_MAX", _SC_MQ_OPEN_MAX, SYSCONF },
02563 #endif
02564 #ifdef _SC_MQ_PRIO_MAX
02565     { "MQ_PRIO_MAX", _SC_MQ_PRIO_MAX, SYSCONF },
02566 #endif
02567 #ifdef _SC_DEVICE_IO
02568     { "_POSIX_DEVICE_IO", _SC_DEVICE_IO, SYSCONF },
02569 #endif
02570 #ifdef _SC_TRACE
02571     { "_POSIX_TRACE", _SC_TRACE, SYSCONF },
02572 #endif
02573 #ifdef _SC_TRACE_EVENT_FILTER
02574     { "_POSIX_TRACE_EVENT_FILTER", _SC_TRACE_EVENT_FILTER, SYSCONF },
02575 #endif
02576 #ifdef _SC_TRACE_INHERIT
02577     { "_POSIX_TRACE_INHERIT", _SC_TRACE_INHERIT, SYSCONF },
02578 #endif
02579 #ifdef _SC_TRACE_LOG
02580     { "_POSIX_TRACE_LOG", _SC_TRACE_LOG, SYSCONF },
02581 #endif
02582 #ifdef _SC_RTSIG_MAX
02583     { "RTSIG_MAX", _SC_RTSIG_MAX, SYSCONF },
02584 #endif
02585 #ifdef _SC_SEM_NSEMS_MAX
02586     { "SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX, SYSCONF },
02587 #endif
02588 #ifdef _SC_SEM_VALUE_MAX
02589     { "SEM_VALUE_MAX", _SC_SEM_VALUE_MAX, SYSCONF },
02590 #endif
02591 #ifdef _SC_SIGQUEUE_MAX
02592     { "SIGQUEUE_MAX", _SC_SIGQUEUE_MAX, SYSCONF },
02593 #endif
02594 #ifdef _PC_FILESIZEBITS
02595     { "FILESIZEBITS", _PC_FILESIZEBITS, PATHCONF },
02596 #endif
02597 #ifdef _PC_ALLOC_SIZE_MIN
02598     { "POSIX_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN, PATHCONF },
02599 #endif
02600 #ifdef _PC_REC_INCR_XFER_SIZE
02601     { "POSIX_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE, PATHCONF },
02602 #endif
02603 #ifdef _PC_REC_MAX_XFER_SIZE
02604     { "POSIX_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE, PATHCONF },
02605 #endif
02606 #ifdef _PC_REC_MIN_XFER_SIZE
02607     { "POSIX_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE, PATHCONF },
02608 #endif
02609 #ifdef _PC_REC_XFER_ALIGN
02610     { "POSIX_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN, PATHCONF },
02611 #endif
02612 #ifdef _PC_SYMLINK_MAX
02613     { "SYMLINK_MAX", _PC_SYMLINK_MAX, PATHCONF },
02614 #endif
02615 #ifdef _CS_GNU_LIBC_VERSION
02616     { "GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION, CONFSTR },
02617 #endif
02618 #ifdef _CS_GNU_LIBPTHREAD_VERSION
02619     { "GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION, CONFSTR },
02620 #endif
02621 #ifdef _PC_2_SYMLINKS
02622     { "POSIX2_SYMLINKS", _PC_2_SYMLINKS, PATHCONF },
02623 #endif
02624 
02625 #ifdef _SC_LEVEL1_ICACHE_SIZE
02626     { "LEVEL1_ICACHE_SIZE", _SC_LEVEL1_ICACHE_SIZE, SYSCONF },
02627 #endif
02628 #ifdef _SC_LEVEL1_ICACHE_ASSOC
02629     { "LEVEL1_ICACHE_ASSOC", _SC_LEVEL1_ICACHE_ASSOC, SYSCONF },
02630 #endif
02631 #ifdef _SC_LEVEL1_ICACHE_LINESIZE
02632     { "LEVEL1_ICACHE_LINESIZE", _SC_LEVEL1_ICACHE_LINESIZE, SYSCONF },
02633 #endif
02634 #ifdef _SC_LEVEL1_DCACHE_SIZE
02635     { "LEVEL1_DCACHE_SIZE", _SC_LEVEL1_DCACHE_SIZE, SYSCONF },
02636 #endif
02637 #ifdef _SC_LEVEL1_DCACHE_ASSOC
02638     { "LEVEL1_DCACHE_ASSOC", _SC_LEVEL1_DCACHE_ASSOC, SYSCONF },
02639 #endif
02640 #ifdef _SC_LEVEL1_DCACHE_LINESIZE
02641     { "LEVEL1_DCACHE_LINESIZE", _SC_LEVEL1_DCACHE_LINESIZE, SYSCONF },
02642 #endif
02643 #ifdef _SC_LEVEL2_CACHE_SIZE
02644     { "LEVEL2_CACHE_SIZE", _SC_LEVEL2_CACHE_SIZE, SYSCONF },
02645 #endif
02646 #ifdef _SC_LEVEL2_CACHE_ASSOC
02647     { "LEVEL2_CACHE_ASSOC", _SC_LEVEL2_CACHE_ASSOC, SYSCONF },
02648 #endif
02649 #ifdef _SC_LEVEL2_CACHE_LINESIZE
02650     { "LEVEL2_CACHE_LINESIZE", _SC_LEVEL2_CACHE_LINESIZE, SYSCONF },
02651 #endif
02652 #ifdef _SC_LEVEL3_CACHE_SIZE
02653     { "LEVEL3_CACHE_SIZE", _SC_LEVEL3_CACHE_SIZE, SYSCONF },
02654 #endif
02655 #ifdef _SC_LEVEL3_CACHE_ASSOC
02656     { "LEVEL3_CACHE_ASSOC", _SC_LEVEL3_CACHE_ASSOC, SYSCONF },
02657 #endif
02658 #ifdef _SC_LEVEL3_CACHE_LINESIZE
02659     { "LEVEL3_CACHE_LINESIZE", _SC_LEVEL3_CACHE_LINESIZE, SYSCONF },
02660 #endif
02661 #ifdef _SC_LEVEL4_CACHE_SIZE
02662     { "LEVEL4_CACHE_SIZE", _SC_LEVEL4_CACHE_SIZE, SYSCONF },
02663 #endif
02664 #ifdef _SC_LEVEL4_CACHE_ASSOC
02665     { "LEVEL4_CACHE_ASSOC", _SC_LEVEL4_CACHE_ASSOC, SYSCONF },
02666 #endif
02667 
02668 #ifdef _SC_IPV6
02669     { "IPV6", _SC_IPV6, SYSCONF },
02670 #endif
02671 #ifdef _SC_RAW_SOCKETS
02672     { "RAW_SOCKETS", _SC_RAW_SOCKETS, SYSCONF },
02673 #endif
02674 
02675     { NULL, 0, SYSCONF }
02676 };
02677 
02678 #define _GETCONF_PATH   "/"
02679 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
02680 static const char *_getconf_path = NULL;
02681 
02682 int
02683 rpmdsGetconf(rpmds * dsp, const char *path)
02684         /*@globals _getconf_path @*/
02685         /*@modifies _getconf_path @*/
02686 {
02687     const struct conf *c;
02688     size_t clen;
02689     long int value;
02690     const char * NS = "getconf";
02691     const char *N;
02692     char * EVR;
02693     char * t;
02694     evrFlags Flags;
02695 
02696 /*@-modobserver@*/
02697     if (_getconf_path == NULL) {
02698         _getconf_path = rpmExpand("%{?_rpmds__getconf_path}", NULL);
02699         /* XXX may need to validate path existence somewhen. */
02700         if (!(_getconf_path != NULL && *_getconf_path == '/')) {
02701 /*@-observertrans @*/
02702             _getconf_path = _free(_getconf_path);
02703 /*@=observertrans @*/
02704             _getconf_path = xstrdup(_GETCONF_PATH);
02705         }
02706     }
02707 /*@=modobserver@*/
02708 
02709     if (path == NULL)
02710         path = _getconf_path;
02711 
02712     for (c = vars; c->name != NULL; ++c) {
02713         N = c->name;
02714         EVR = NULL;
02715         switch (c->call) {
02716         case PATHCONF:
02717             value = pathconf(path, c->call_name);
02718             if (value != -1) {
02719                 EVR = xmalloc(32);
02720                 sprintf(EVR, "%ld", value);
02721             }
02722             /*@switchbreak@*/ break;
02723         case SYSCONF:
02724             value = sysconf(c->call_name);
02725             if (value == -1l) {
02726 #if defined(_SC_UINT_MAX) && defined(_SC_ULONG_MAX)
02727 /*@-unrecog@*/
02728                 if (c->call_name == _SC_UINT_MAX
02729                 || c->call_name == _SC_ULONG_MAX) {
02730                     EVR = xmalloc(32);
02731                     sprintf(EVR, "%lu", value);
02732                 }
02733 /*@=unrecog@*/
02734 #endif
02735             } else {
02736                 EVR = xmalloc(32);
02737                 sprintf(EVR, "%ld", value);
02738             }
02739             /*@switchbreak@*/ break;
02740         case CONFSTR:
02741 #ifndef __CYGWIN__
02742             clen = confstr(c->call_name, (char *) NULL, 0);
02743             EVR = xmalloc(clen+1);
02744             *EVR = '\0';
02745             if (confstr (c->call_name, EVR, clen) != clen) {
02746                 fprintf(stderr, "confstr: %s\n", strerror(errno));
02747                 exit (EXIT_FAILURE);
02748             }
02749             EVR[clen] = '\0';
02750 #endif
02751             /*@switchbreak@*/ break;
02752         }
02753         if (EVR == NULL)
02754             continue;
02755 
02756         for (t = EVR; *t; t++) {
02757             if (*t == '\n') *t = ' ';
02758         }
02759         if (!strcmp(N, "GNU_LIBC_VERSION")
02760          || !strcmp(N, "GNU_LIBPTHREAD_VERSION"))
02761         {
02762             for (t = EVR; *t; t++) {
02763                 if (*t == ' ') *t = '-';
02764             }
02765         }
02766 
02767         if (*EVR == '\0' || strchr(EVR, ' ') != NULL
02768          || (EVR[0] == '-' && strchr("0123456789", EVR[1]) == NULL))
02769         {
02770             EVR = _free(EVR);
02771             continue;
02772         }
02773 
02774         Flags = RPMSENSE_PROBE|RPMSENSE_EQUAL;
02775         rpmdsNSAdd(dsp, NS, N, EVR, Flags);
02776         EVR = _free(EVR);
02777     }
02778     return 0;
02779 }
02780 
02781 int rpmdsMergePRCO(void * context, rpmds ds)
02782 {
02783     rpmPRCO PRCO = context;
02784     int rc = -1;
02785 
02786 /*@-modfilesys@*/
02787 if (_rpmds_debug < 0)
02788 fprintf(stderr, "*** rpmdsMergePRCO(%p, %p) %s\n", context, ds, rpmdsTagName(rpmdsTagN(ds)));
02789 /*@=modfilesys@*/
02790     switch(rpmdsTagN(ds)) {
02791     default:
02792         break;
02793     case RPMTAG_PROVIDENAME:
02794         rc = rpmdsMerge(PRCO->Pdsp, ds);
02795         break;
02796     case RPMTAG_REQUIRENAME:
02797         rc = rpmdsMerge(PRCO->Rdsp, ds);
02798         break;
02799     case RPMTAG_CONFLICTNAME:
02800         rc = rpmdsMerge(PRCO->Cdsp, ds);
02801         break;
02802     case RPMTAG_OBSOLETENAME:
02803         rc = rpmdsMerge(PRCO->Odsp, ds);
02804         break;
02805     case RPMTAG_TRIGGERNAME:
02806         rc = rpmdsMerge(PRCO->Tdsp, ds);
02807         break;
02808     case RPMTAG_DIRNAMES:
02809         rc = rpmdsMerge(PRCO->Ddsp, ds);
02810         break;
02811     case RPMTAG_FILELINKTOS:
02812         rc = rpmdsMerge(PRCO->Ldsp, ds);
02813         break;
02814     }
02815     return rc;
02816 }
02817 
02818 rpmPRCO rpmdsFreePRCO(rpmPRCO PRCO)
02819 {
02820     if (PRCO) {
02821         (void)rpmdsFree(PRCO->this);
02822         PRCO->this = NULL;
02823         (void)rpmdsFree(PRCO->P);
02824         PRCO->P = NULL;
02825         (void)rpmdsFree(PRCO->R);
02826         PRCO->R = NULL;
02827         (void)rpmdsFree(PRCO->C);
02828         PRCO->C = NULL;
02829         (void)rpmdsFree(PRCO->O);
02830         PRCO->O = NULL;
02831         (void)rpmdsFree(PRCO->T);
02832         PRCO->T = NULL;
02833         (void)rpmdsFree(PRCO->D);
02834         PRCO->D = NULL;
02835         (void)rpmdsFree(PRCO->L);
02836         PRCO->L = NULL;
02837         memset(PRCO, 0, sizeof(*PRCO));
02838         PRCO = _free(PRCO);
02839     }
02840     return NULL;
02841 }
02842 
02843 rpmPRCO rpmdsNewPRCO(Header h)
02844 {
02845     rpmPRCO PRCO = xcalloc(1, sizeof(*PRCO));
02846 
02847     if (h != NULL) {
02848         static int scareMem = 0;
02849         PRCO->this = rpmdsNew(h, RPMTAG_NAME, scareMem);
02850         PRCO->P = rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem);
02851         PRCO->R = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem);
02852         PRCO->C = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem);
02853         PRCO->O = rpmdsNew(h, RPMTAG_OBSOLETENAME, scareMem);
02854         PRCO->T = rpmdsNew(h, RPMTAG_TRIGGERNAME, scareMem);
02855         PRCO->D = rpmdsNew(h, RPMTAG_DIRNAMES, scareMem);
02856         PRCO->L = rpmdsNew(h, RPMTAG_FILELINKTOS, scareMem);
02857     }
02858     PRCO->Pdsp =  &PRCO->P;
02859     PRCO->Rdsp =  &PRCO->R;
02860     PRCO->Cdsp =  &PRCO->C;
02861     PRCO->Odsp =  &PRCO->O;
02862     PRCO->Tdsp =  &PRCO->T;
02863     PRCO->Ddsp =  &PRCO->D;
02864     PRCO->Ldsp =  &PRCO->L;
02865     return PRCO;
02866 }
02867 
02868 rpmds rpmdsFromPRCO(rpmPRCO PRCO, rpmTag tagN)
02869 {
02870     /*@-compdef -refcounttrans -retalias -retexpose -usereleased @*/
02871     if (PRCO != NULL)
02872     switch (tagN) {
02873     default:    break;
02874     case RPMTAG_NAME:           return PRCO->this;      /*@notreached@*/ break;
02875     case RPMTAG_PROVIDENAME:    return *PRCO->Pdsp;     /*@notreached@*/ break;
02876     case RPMTAG_REQUIRENAME:    return *PRCO->Rdsp;     /*@notreached@*/ break;
02877     case RPMTAG_CONFLICTNAME:   return *PRCO->Cdsp;     /*@notreached@*/ break;
02878     case RPMTAG_OBSOLETENAME:   return *PRCO->Odsp;     /*@notreached@*/ break;
02879     case RPMTAG_TRIGGERNAME:    return *PRCO->Tdsp;     /*@notreached@*/ break;
02880     case RPMTAG_DIRNAMES:       return *PRCO->Ddsp;     /*@notreached@*/ break;
02881     case RPMTAG_FILELINKTOS:    return *PRCO->Ldsp;     /*@notreached@*/ break;
02882     }
02883     return NULL;
02884     /*@=compdef =refcounttrans =retalias =retexpose =usereleased @*/
02885 }
02886 
02893 #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
02894 #if defined(RPM_VENDOR_MANDRIVA)
02895 static char * sonameDep(/*@returned@*/ char * t, const char * s, int isElf64, int devel, int uClibc)
02896         /*@modifies t @*/
02897 {
02898     char *tmp = t;
02899     *t = '\0';
02900     if (uClibc)
02901         tmp = stpcpy(tmp, "uClibc(");
02902     if (devel) {
02903         tmp = stpcpy(tmp, "devel(");
02904     }
02905 #if !defined(__alpha__) && !defined(__sun)
02906     if (isElf64) {
02907         /* XXX: eehhk, would've been nice with consistency, mandriva legacy... :| */
02908         if (!devel && s[strlen(s)-1] != ')')
02909         tmp = stpcpy( stpcpy(tmp, s), "()(64bit)");
02910     else {
02911             tmp = stpcpy(tmp, s);
02912             if (devel)
02913                 tmp = strstr(t, ".so");
02914             tmp = stpcpy(tmp, "(64bit)");
02915         }
02916     }else
02917 #endif
02918         tmp = stpcpy(tmp, s);
02919     if (devel) {
02920         char *suffix = strstr(t, ".so");
02921         if (suffix)
02922             tmp = suffix;
02923         tmp = stpcpy(tmp, ")");
02924     }
02925     if (uClibc)
02926         tmp = stpcpy(tmp, ")");
02927 
02928     return t;
02929 }
02930 
02931 static char *find_elf_interpreter(GElf_Ehdr *ehdr, Elf *elf, char *filename)
02932 {
02933     FILE *fp = NULL;
02934     struct stat statbuf;
02935     GElf_Ehdr ehdr_mem;
02936     GElf_Shdr shdr_mem, *shdr;
02937     GElf_Phdr phdr_mem, *phdr;
02938     GElf_Dyn dyn_mem, *dyn;
02939     Elf_Data * data;
02940     Elf_Scn *scn = NULL;
02941     int fdno;
02942     char *interp_name = NULL;
02943     char *libpath = NULL;
02944     int cnt;
02945     int class;
02946     size_t shstrndx;
02947 
02948     if (filename) {
02949         if (!(fp = fopen(filename, "r"))) {
02950             perror(filename);
02951             return NULL;
02952         }
02953         if (fstat((fdno = fileno(fp)), &statbuf) < 0) {
02954             perror(filename);
02955             goto end;
02956         }
02957         if ((size_t) statbuf.st_size < sizeof(Elf64_Ehdr) || !S_ISREG(statbuf.st_mode))
02958             goto foo;
02959 
02960         (void) elf_version(EV_CURRENT);
02961         elf = NULL;
02962         if ((elf = elf_begin (fdno, ELF_C_READ, NULL)) == NULL
02963                 || elf_kind(elf) != ELF_K_ELF
02964                 || (ehdr = gelf_getehdr(elf, &ehdr_mem)) == NULL
02965                 || !(ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC))
02966             goto end;
02967     }
02968 foo:
02969 
02970     if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
02971         fprintf(stderr, "%s: not a dynamic executable\n", filename);
02972         goto end;
02973     }
02974     class = gelf_getclass(elf);
02975 
02976     for (cnt = 0; cnt < ehdr->e_phnum; cnt++) {
02977         phdr = gelf_getphdr (elf, cnt, &phdr_mem);
02978         if (phdr->p_type == PT_INTERP)
02979             break;
02980         phdr = NULL;
02981     }
02982     if (phdr) {
02983         Elf_Data *data = NULL;
02984 
02985         scn = gelf_offscn (elf, phdr->p_offset);
02986         shdr = gelf_getshdr(scn, &shdr_mem);
02987         data = elf_getdata (scn, data);
02988         if (data && data->d_buf) {
02989             interp_name = strdup(data->d_buf);
02990             goto end;
02991         }
02992         /* no 'data' most likely implies that this is an elf interpreter itself */
02993     }
02994 
02995     if (elf_getshdrstrndx (elf, &shstrndx) >= 0)
02996         while ((scn = elf_nextscn(elf, scn)) != NULL) {
02997             shdr = gelf_getshdr(scn, &shdr_mem);
02998             if (shdr->sh_type == SHT_DYNAMIC) {
02999                 char *rpath = NULL;
03000                 for (cnt = 0; cnt < ehdr->e_phnum; cnt++) {
03001                     phdr = gelf_getphdr (elf, cnt, &phdr_mem);
03002                     if (phdr->p_type == PT_LOAD)
03003                         break;
03004                 }
03005 
03006                 data = NULL;
03007                 while ((data = elf_getdata (scn, data)) != NULL) {
03008                     int dynsize = (int)(shdr->sh_size / shdr->sh_entsize)-1;
03009                     for (cnt = 0; cnt <= dynsize; ++cnt) {
03010                         dyn = gelf_getdyn (data, cnt, &dyn_mem);
03011 
03012                         /* if this an elf interpeter, the only thing we want is to find SONAME
03013                          * and return it
03014                          */
03015                         if (phdr) {
03016                             if (dyn->d_tag != DT_SONAME)
03017                                 continue;
03018                             interp_name = strdup(elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val));
03019                             goto end;
03020                         }
03021                         if (rpath == NULL) {
03022                             if (dyn->d_tag == DT_RPATH)
03023                                 rpath = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
03024                             else if (cnt == dynsize)
03025                                 rpath = "";
03026                             if (rpath != NULL)
03027                                 cnt = -1;
03028                             continue;
03029                         }
03030                         else if (rpath && dyn->d_tag == DT_NEEDED) {
03031                             char *tmp, *tmp2;
03032                             char buf[1024];
03033                             char path[1024] = "";
03034 
03035                             libpath = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
03036 
03037                             if (!libpath || !strlen(libpath))
03038                                 continue;
03039 
03040                             tmp = libpath;
03041                             while (*tmp) {
03042                                 if (*tmp == '/')
03043                                     libpath = tmp + 1;
03044                                 tmp++;
03045                             }
03046 
03047                             /* If this is a fully resolved name, we don't need to modify the path */
03048                             if (stat(libpath, &statbuf) == 0)
03049                                 continue;
03050 
03051                             tmp2 = path;
03052                             if (rpath && *rpath) {
03053                                 tmp2 = stpcpy(tmp2, rpath);
03054                                 tmp2 = stpcpy(tmp2, ":");
03055                             }
03056                             tmp = getenv("LD_LIBRARY_PATH");
03057                             if (tmp)
03058                                 tmp2 = stpcpy(tmp2, tmp);
03059                             if ((rpath && *rpath) || tmp)
03060                                 tmp2 = stpcpy(tmp2, ":");
03061                             /* XXX: do better check to ensure libraries are all of the same class */
03062                             tmp2 = stpcpy(tmp2, (class == ELFCLASS64) ? "/lib64" : "/lib");
03063                             tmp = buf;
03064                             {
03065                                 int i, count = 1;
03066                                 char *path_n;
03067 
03068                                 /* Eliminate all double //s */
03069                                 path_n = path;
03070                                 while ((path_n = strstr(path_n, "//"))) {
03071                                     i = strlen(path_n);
03072                                     memmove(path_n, path_n + 1, i - 1);
03073                                     *(path_n + i - 1) = '\0';
03074                                 }
03075 
03076                                 /* Replace colons with zeros in path_list and count them */
03077                                 for (i = strlen(path); i > 0; i--) {
03078                                     if (path[i] == ':') {
03079                                         path[i] = 0;
03080                                         count++;
03081                                     }
03082                                 }
03083                                 path_n = path;
03084                                 for (i = 0; i < count; i++) {
03085                                     strcpy(tmp, path_n);
03086                                     strcat(tmp, "/");
03087                                     strcat(tmp, libpath);
03088 
03089                                     if (stat(tmp, &statbuf) == 0 && statbuf.st_mode & S_IRUSR) {
03090                                         path[0] = '\0';
03091                                         break;
03092                                     }
03093                                     path_n += (strlen(path_n) + 1);
03094                                 }
03095                                 if(path[0])
03096                                     *tmp = '\0';
03097                             }
03098                             libpath = buf;
03099                         }
03100                     }
03101                 }
03102                 break;
03103             }
03104         }
03105 
03106 end:
03107     if (fp) {
03108         if (elf) (void) elf_end(elf);
03109         fclose(fp);
03110     }
03111     if (!interp_name && libpath)
03112         return find_elf_interpreter(NULL, NULL, libpath);
03113     return interp_name;
03114 }
03115 
03116 static int checkuClibc(GElf_Ehdr *ehdr, Elf *elf) {
03117     int ret = 0;
03118     char *interp = find_elf_interpreter(ehdr, elf, NULL);
03119 
03120     if (interp) {
03121         char *tmp = basename(interp);
03122         if (tmp[0] == 'l' && tmp[1] == 'd') {
03123             tmp += ((tmp[2] == '3' && tmp[3] == '2') ||
03124                     (tmp[2] == '6' && tmp[3] == '4')) ?
03125                 5 : 7;
03126             if (!strncasecmp(tmp, "uClibc.so", sizeof("uClibc.so")-1))
03127                 ret = 1;
03128         }
03129         free(interp);
03130     }
03131     return ret;
03132 }
03133 #else
03134 static char * sonameDep(/*@returned@*/ char * t, const char * s, int isElf64, int devel, int uClibc)
03135         /*@modifies t @*/
03136 {
03137     *t = '\0';
03138 #if !defined(__alpha__) && !defined(__sun)
03139     if (isElf64) {
03140         if (s[strlen(s)-1] != ')')
03141         (void) stpcpy( stpcpy(t, s), "()(64bit)");
03142     else
03143             (void) stpcpy( stpcpy(t, s), "(64bit)");
03144     }else
03145 #endif
03146         (void) stpcpy(t, s);
03147     return t;
03148 }
03149 #endif
03150 #endif
03151 
03152 /*@-moduncon -noeffectuncon @*/
03153 int rpmdsELF(const char * fn, int flags,
03154                 int (*add) (void * context, rpmds ds), void * context)
03155 {
03156 #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
03157     Elf * elf;
03158     Elf_Scn * scn;
03159     Elf_Data * data;
03160     GElf_Ehdr ehdr_mem, * ehdr;
03161     GElf_Shdr shdr_mem, * shdr;
03162     GElf_Verdef def_mem, * def;
03163     GElf_Verneed need_mem, * need;
03164     GElf_Dyn dyn_mem, * dyn;
03165     unsigned int auxoffset;
03166     unsigned int offset;
03167     int fdno;
03168     int cnt2;
03169     int cnt;
03170     char buf[BUFSIZ];
03171     const char * s;
03172     int is_executable;
03173     const char * soname = NULL;
03174     rpmds ds;
03175     char * t;
03176     int xx;
03177     int isElf64;
03178     int isDSO;
03179     int isuClibc;
03180     int gotSONAME = 0;
03181     int gotDEBUG = 0;
03182     int gotHASH = 0;
03183     int gotGNUHASH = 0;
03184     int skipP = (flags & RPMELF_FLAG_SKIPPROVIDES);
03185     int skipR = (flags & RPMELF_FLAG_SKIPREQUIRES);
03186     static int filter_GLIBC_PRIVATE = 0;
03187     static int oneshot = 0;
03188 
03189 /*@-castfcnptr@*/
03190 if (_rpmds_debug < 0)
03191 fprintf(stderr, "*** rpmdsELF(%s, %d, %p, %p)\n", fn, flags, (void *)add, context);
03192 /*@=castfcnptr@*/
03193     if (oneshot == 0) {
03194         oneshot = 1;
03195         filter_GLIBC_PRIVATE = rpmExpandNumeric("%{?_filter_GLIBC_PRIVATE}");
03196     }
03197 
03198     /* Extract dependencies only from files with executable bit set. */
03199     {   struct stat sb, * st = &sb;
03200         if (stat(fn, st) != 0)
03201             return -1;
03202         is_executable = (int)(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
03203     }
03204 
03205     fdno = open(fn, O_RDONLY);
03206     if (fdno < 0)
03207         return fdno;
03208 
03209     (void) elf_version(EV_CURRENT);
03210 
03211 /*@-evalorder@*/
03212     elf = NULL;
03213     if ((elf = elf_begin (fdno, ELF_C_READ, NULL)) == NULL
03214      || elf_kind(elf) != ELF_K_ELF
03215      || (ehdr = gelf_getehdr(elf, &ehdr_mem)) == NULL
03216      || !(ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC))
03217         goto exit;
03218 /*@=evalorder@*/
03219 
03220     isElf64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
03221     isDSO = ehdr->e_type == ET_DYN;
03222 #if defined(RPM_VENDOR_MANDRIVA)
03223     isuClibc = checkuClibc(ehdr, elf);
03224 #else
03225     isuClibc = 0;
03226 #endif
03227 
03228     /*@-uniondef @*/
03229     scn = NULL;
03230     while ((scn = elf_nextscn(elf, scn)) != NULL) {
03231         shdr = gelf_getshdr(scn, &shdr_mem);
03232         if (shdr == NULL)
03233             break;
03234 
03235         soname = _free(soname);
03236         switch (shdr->sh_type) {
03237         default:
03238             continue;
03239             /*@notreached@*/ /*@switchbreak@*/ break;
03240         case SHT_NOTE:
03241 #if defined(HAVE_GELF_GETNOTE)  /* XXX OpenIndiana & older elfutils haven't. */
03242             if (!(shdr->sh_flags & SHF_ALLOC))
03243                 continue;
03244             data = NULL;
03245             while ((data = elf_getdata(scn, data)) != NULL) {
03246                 GElf_Nhdr nhdr;
03247                 size_t name_offset;
03248                 size_t desc_offset;
03249                 offset = 0;
03250                 while (offset < data->d_size
03251                  && (offset = gelf_getnote(data, offset,
03252                         &nhdr, &name_offset, &desc_offset)) > 0)
03253                 {
03254                     const char *name = ((char *)data->d_buf) + name_offset;
03255                     const char *desc = ((char *)data->d_buf) + desc_offset;
03256                     if (memchr(name, '\0', nhdr.n_namesz) == NULL)
03257                         /*@innercontinue@*/ continue;
03258                     switch (nhdr.n_type) {
03259                     default:    /*@innercontinue@*/ continue;
03260 #if !defined(NT_GNU_BUILD_ID)
03261 #define NT_GNU_BUILD_ID 3
03262 #endif
03263                     case NT_GNU_BUILD_ID:
03264                         if (strcmp(name, "GNU") == 0 && nhdr.n_descsz > 0) {  
03265                             static const char hex[] = "0123456789abcdef";
03266                             size_t i;
03267                             buf[0] = '\0';
03268                             t = buf;
03269                             for (i = 0; i < nhdr.n_descsz; ++i) {
03270                                 *t++ = hex[ (((unsigned)desc[i] >> 4) & 0x0f) ];
03271                                 *t++ = hex[ (((unsigned)desc[i]     ) & 0x0f) ];
03272                             }
03273                             *t = '\0';
03274                             /* Add next buildid. */
03275                             ds = rpmdsSingle(RPMTAG_PROVIDES, "elf(buildid)",
03276                                         buf, RPMSENSE_EQUAL|RPMSENSE_FIND_PROVIDES);
03277                             xx = add(context, ds);
03278                             (void)rpmdsFree(ds);
03279                             ds = NULL;
03280                         }
03281                         /*@switchbreak@*/ break;
03282                     }
03283                 }
03284             }
03285 #endif  /* defined(HAVE_GELF_GETNOTE) */
03286             /*@switchbreak@*/ break;
03287         case SHT_GNU_verdef:
03288             data = NULL;
03289             if (!skipP)
03290             while ((data = elf_getdata (scn, data)) != NULL) {
03291                 offset = 0;
03292                 for (cnt = (int)shdr->sh_info; --cnt >= 0; ) {
03293                 
03294                     def = gelf_getverdef (data, offset, &def_mem);
03295                     if (def == NULL)
03296                         /*@innerbreak@*/ break;
03297                     auxoffset = (unsigned)(offset + def->vd_aux);
03298                     for (cnt2 = (int)def->vd_cnt; --cnt2 >= 0; ) {
03299                         GElf_Verdaux aux_mem, * aux;
03300 
03301                         aux = gelf_getverdaux (data, auxoffset, &aux_mem);
03302                         if (aux == NULL)
03303                             /*@innerbreak@*/ break;
03304 
03305                         s = elf_strptr(elf, shdr->sh_link, aux->vda_name);
03306                         if (s == NULL)
03307                             /*@innerbreak@*/ break;
03308 
03309                         if (def->vd_flags & VER_FLG_BASE) {
03310                             soname = _free(soname);
03311                             soname = xstrdup(s);
03312                         } else
03313                         if (soname != NULL
03314                          && !(filter_GLIBC_PRIVATE != 0
03315                                 && !strcmp(s, "GLIBC_PRIVATE")))
03316                         {
03317                             buf[0] = '\0';
03318                             t = buf;
03319                             t = stpcpy( stpcpy( stpcpy( stpcpy(t, soname), "("), s), ")");
03320 
03321                             t++;        /* XXX "foo(bar)" already in buf. */
03322 
03323                             /* Add next provide dependency. */
03324                             ds = rpmdsSingle(RPMTAG_PROVIDES,
03325                                         sonameDep(t, buf, isElf64, 0, isuClibc),
03326                                         "", RPMSENSE_FIND_PROVIDES);
03327                             xx = add(context, ds);
03328                             (void)rpmdsFree(ds);
03329                             ds = NULL;
03330                         }
03331                         auxoffset += aux->vda_next;
03332                     }
03333                     offset += def->vd_next;
03334                 }
03335             }
03336             /*@switchbreak@*/ break;
03337         case SHT_GNU_verneed:
03338             data = NULL;
03339             /* Only from files with executable bit set. */
03340             if (!skipR && is_executable)
03341             while ((data = elf_getdata (scn, data)) != NULL) {
03342                 offset = 0;
03343                 for (cnt = (int)shdr->sh_info; --cnt >= 0; ) {
03344                     need = gelf_getverneed (data, offset, &need_mem);
03345                     if (need == NULL)
03346                         /*@innerbreak@*/ break;
03347 
03348                     s = elf_strptr(elf, shdr->sh_link, need->vn_file);
03349                     if (s == NULL)
03350                         /*@innerbreak@*/ break;
03351                     soname = _free(soname);
03352                     soname = xstrdup(s);
03353                     auxoffset = (unsigned)(offset + need->vn_aux);
03354                     for (cnt2 = (int)need->vn_cnt; --cnt2 >= 0; ) {
03355                         GElf_Vernaux aux_mem, * aux;
03356 
03357                         aux = gelf_getvernaux (data, auxoffset, &aux_mem);
03358                         if (aux == NULL)
03359                             /*@innerbreak@*/ break;
03360 
03361                         s = elf_strptr(elf, shdr->sh_link, aux->vna_name);
03362                         if (s == NULL)
03363                             /*@innerbreak@*/ break;
03364 
03365                         /* Filter dependencies that contain GLIBC_PRIVATE */
03366                         if (soname != NULL
03367                          && !(filter_GLIBC_PRIVATE != 0
03368                                 && !strcmp(s, "GLIBC_PRIVATE")))
03369                         {
03370                             buf[0] = '\0';
03371                             t = buf;
03372                             t = stpcpy( stpcpy( stpcpy( stpcpy(t, soname), "("), s), ")");
03373 
03374                             t++;        /* XXX "foo(bar)" already in buf. */
03375 
03376                             /* Add next require dependency. */
03377                             ds = rpmdsSingle(RPMTAG_REQUIRENAME,
03378                                         sonameDep(t, buf, isElf64, 0, isuClibc),
03379                                         "", RPMSENSE_FIND_REQUIRES);
03380                             xx = add(context, ds);
03381                             (void)rpmdsFree(ds);
03382                             ds = NULL;
03383                         }
03384                         auxoffset += aux->vna_next;
03385                     }
03386                     offset += need->vn_next;
03387                 }
03388             }
03389             /*@switchbreak@*/ break;
03390         case SHT_DYNAMIC:
03391             data = NULL;
03392             while ((data = elf_getdata (scn, data)) != NULL) {
03393                 for (cnt = 0; cnt < (int)(shdr->sh_size / shdr->sh_entsize); ++cnt) {
03394                     dyn = gelf_getdyn (data, cnt, &dyn_mem);
03395                     if (dyn == NULL)
03396                         /*@innerbreak@*/ break;
03397                     s = NULL;
03398                     switch (dyn->d_tag) {
03399                     default:
03400                         /*@innercontinue@*/ continue;
03401                         /*@notreached@*/ /*@switchbreak@*/ break;
03402                     case DT_HASH:
03403                         gotHASH= 1;
03404                         /*@innercontinue@*/ continue;
03405                     case DT_GNU_HASH:
03406                         gotGNUHASH= 1;
03407                         /*@innercontinue@*/ continue;
03408                     case DT_DEBUG:    
03409                         gotDEBUG = 1;
03410                         /*@innercontinue@*/ continue;
03411                     case DT_NEEDED:
03412                         /* Only from files with executable bit set. */
03413                         if (skipR || !is_executable)
03414                             /*@innercontinue@*/ continue;
03415                         /* Add next require dependency. */
03416                         s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
03417 assert(s != NULL);
03418                         buf[0] = '\0';
03419                         ds = rpmdsSingle(RPMTAG_REQUIRENAME,
03420                                 sonameDep(buf, s, isElf64, 0, isuClibc),
03421                                 "", RPMSENSE_FIND_REQUIRES);
03422                         xx = add(context, ds);
03423                         (void)rpmdsFree(ds);
03424                         ds = NULL;
03425                         /*@switchbreak@*/ break;
03426                     case DT_SONAME:
03427                         gotSONAME = 1;
03428                         if (skipP)
03429                             /*@innercontinue@*/ continue;
03430                         s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
03431 assert(s != NULL);
03432                         /* Add next provide dependency. */
03433                         buf[0] = '\0';
03434                         ds = rpmdsSingle(RPMTAG_PROVIDENAME,
03435                                 sonameDep(buf, s, isElf64, 0, isuClibc),
03436                                 "", RPMSENSE_FIND_PROVIDES);
03437                         xx = add(context, ds);
03438                         (void)rpmdsFree(ds);
03439                         ds = NULL;
03440                         /*@switchbreak@*/ break;
03441                     }
03442                 }
03443             }
03444             /*@switchbreak@*/ break;
03445         }
03446     }
03447     /*@=uniondef @*/
03448 
03449     /* For DSOs which use the .gnu_hash section and don't have a .hash
03450      * section, we need to ensure that we have a new enough glibc. */
03451     if (gotGNUHASH && !gotHASH) {
03452         ds = rpmdsSingle(RPMTAG_REQUIRENAME, "rtld(GNU_HASH)", "",
03453                         RPMSENSE_FIND_REQUIRES);
03454         xx = add(context, ds);
03455         (void)rpmdsFree(ds);
03456         ds = NULL;
03457     }
03458 
03459     /* For DSO's, provide the basename of the file if DT_SONAME not found. */
03460     if (!skipP && isDSO && !gotDEBUG && !gotSONAME) {
03461         s = strrchr(fn, '/');
03462         if (s != NULL)
03463             s++;
03464         else
03465             s = fn;
03466 assert(s != NULL);
03467 
03468         /* Add next provide dependency. */
03469         buf[0] = '\0';
03470         ds = rpmdsSingle(RPMTAG_PROVIDENAME,
03471                 sonameDep(buf, s, isElf64, 0, isuClibc), "", RPMSENSE_FIND_PROVIDES);
03472         xx = add(context, ds);
03473         (void)rpmdsFree(ds);
03474         ds = NULL;
03475     }
03476 
03477 exit:
03478     soname = _free(soname);
03479     if (elf) (void) elf_end(elf);
03480     if (fdno > 0)
03481         xx = close(fdno);
03482     return 0;
03483 #else
03484     return -1;
03485 #endif
03486 }
03487 /*@=moduncon =noeffectuncon @*/
03488 
03489 
03490 #if defined(RPM_VENDOR_MANDRIVA)
03491 
03500 int rpmdsSymlink(const char * fn, int flags,
03501                 int (*add) (void * context, rpmds ds), void * context)
03502         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
03503         /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
03504 int rpmdsSymlink(const char * fn, int flags,
03505                 int (*add) (void * context, rpmds ds), void * context)
03506 {
03507 #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
03508     Elf * elf;
03509     Elf_Scn * scn;
03510     Elf_Data * data;
03511     GElf_Ehdr ehdr_mem, * ehdr;
03512     GElf_Shdr shdr_mem, * shdr;
03513     GElf_Dyn dyn_mem, * dyn;
03514     int fdno;
03515     int cnt;
03516     int i;
03517     char buf[BUFSIZ];
03518     const char * s;
03519     int is_executable;
03520     int is_symlink;
03521     const char * soname = NULL;
03522     rpmds ds;
03523     int xx;
03524     int isElf64;
03525     int isuClibc;
03526     int gotSONAME = 0;
03527     int skipP = (flags & RPMELF_FLAG_SKIPPROVIDES);
03528     int skipR = (flags & RPMELF_FLAG_SKIPREQUIRES);
03529     int lnklen;
03530     char path[MAXPATHLEN];
03531     /*
03532      * We filter out these as they come with glibc, making dependencies on
03533      * them rather redundant.
03534      */
03535     const char *filterRequires[] = {"ld-linux", "ld64-linux" "libBrokenLocale.so",
03536         "libanl.so", "libc.so", "libcidn.so", "libcrypt.so", "libdl.so", "libm.so",
03537         "libnsl.so", "libnss_compat.so", "libnss_dns.so", "libnss_files.so",
03538         "libnss_hesiod.so", "libnss_nis.so", "libnss_nisplus.so", "libpthread.so",
03539         "libresolv.so", "librt.so", "libutil.so", "libthread_db.so"};
03540     ARGV_t deps = NULL;
03541 
03542     /* Filename must end with ".so" to be devel(...) dependency. */
03543     if ((s = strrchr(fn, '.')) && strcmp(s, ".so"))
03544         return 0;
03545 
03546 /*@-castfcnptr@*/
03547 if (_rpmds_debug < 0)
03548 fprintf(stderr, "*** rpmdsELF(%s, %d, %p, %p)\n", fn, flags, (void *)add, context);
03549 /*@=castfcnptr@*/
03550 
03551     /* Extract dependencies only from files with executable bit set. */
03552     {   struct stat sb, * st = &sb;
03553         if (lstat(fn, st) != 0)
03554             return -1;
03555         is_executable = (int)(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
03556         is_symlink = S_ISLNK(st->st_mode);
03557     }
03558 
03559     if (is_symlink) {
03560 #ifdef NOT_YET
03561         if ((lnklen = readlink(fn, path, MAXPATHLEN - 1)) == -1) {
03562             warn("%s", fn);
03563             return -1;
03564         }
03565         /* XXX: unused, path should expand to absolute path... */
03566         path[lnklen] = '\0';
03567 #endif
03568     } else {
03569         FILE *fp = fopen(fn, "r");
03570         char buf[BUFSIZ];
03571         char *in;
03572         stpcpy(path, fn);
03573         fn = NULL;
03574         if (fp == NULL || ferror(fp)) {
03575             if (fp) (void) fclose(fp);
03576             return -1;
03577         }
03578         /* try resolve ld scripts
03579          * certainly *not* state of the art, but should in practice work
03580          * everywhere where relevant...
03581          */
03582         while ((in = fgets(buf, sizeof(buf) - 1, fp))) {
03583             in[sizeof(buf)-1] = '\0';
03584             if ((in = strstr(in, "GROUP")) &&
03585                     (in = strchr(in, '(')) &&
03586                     (fn = strchr(in, '/')) &&
03587                     (in = strchr(fn, ' '))) {
03588                 *in = '\0';
03589                 break;
03590             }
03591             if (ferror(fp) || feof(fp))
03592                 break;
03593         }
03594         fclose(fp);
03595         if (!fn)
03596             return -1;
03597         else {
03598             /* XXX: try determine relative root */
03599             struct stat sb, * st = &sb;
03600 
03601             while((in = strrchr(path, '/'))) {
03602                 stpcpy(in, fn);
03603                 if (stat(path, st) == 0) {
03604                     fn = path;
03605                     break;
03606                 }
03607                 *in = 0;
03608             }
03609             if (!fn)
03610                 return -1;
03611         }
03612     }
03613 
03614     fdno = open(fn, O_RDONLY);
03615     if (fdno < 0)
03616         return fdno;
03617 
03618     (void) elf_version(EV_CURRENT);
03619 
03620 /*@-evalorder@*/
03621     elf = NULL;
03622     if ((elf = elf_begin (fdno, ELF_C_READ, NULL)) == NULL
03623      || elf_kind(elf) != ELF_K_ELF
03624      || (ehdr = gelf_getehdr(elf, &ehdr_mem)) == NULL
03625      || !(ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC))
03626         goto exit;
03627 /*@=evalorder@*/
03628 
03629     isElf64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
03630 #if defined(RPM_VENDOR_MANDRIVA)
03631     isuClibc = checkuClibc(ehdr, elf);
03632 #else
03633     isuClibc = 0;
03634 #endif
03635 
03636     /*@-uniondef @*/
03637     scn = NULL;
03638     while ((scn = elf_nextscn(elf, scn)) != NULL) {
03639         shdr = gelf_getshdr(scn, &shdr_mem);
03640         if (shdr == NULL)
03641             break;
03642 
03643         soname = _free(soname);
03644         switch (shdr->sh_type) {
03645         default:
03646             continue;
03647             /*@notreached@*/ /*@switchbreak@*/ break;
03648         case SHT_DYNAMIC:
03649             data = NULL;
03650             while ((data = elf_getdata (scn, data)) != NULL) {
03651                 for (cnt = 0; cnt < (int)(shdr->sh_size / shdr->sh_entsize); ++cnt) {
03652                     dyn = gelf_getdyn (data, cnt, &dyn_mem);
03653                     if (dyn == NULL)
03654                         /*@innerbreak@*/ break;
03655                     s = NULL;
03656                     switch (dyn->d_tag) {
03657                     default:
03658                         /*@innercontinue@*/ continue;
03659                         /*@notreached@*/ /*@switchbreak@*/ break;
03660                     case DT_NEEDED:
03661                         /* Only from files with executable bit set. */
03662                         if (skipR || !is_executable)
03663                             /*@innercontinue@*/ continue;
03664                         /* Add next require dependency. */
03665                         s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
03666 assert(s != NULL);
03667                         buf[0] = '\0';
03668 
03669                         for (i = 0; i < (int)(sizeof(filterRequires)/sizeof(filterRequires[0])); i++)
03670                             if (!strncmp(s, filterRequires[i], strlen(filterRequires[i])) && !isuClibc)
03671                                 break;
03672 
03673                         if (sizeof(filterRequires)/sizeof(filterRequires[0]) == i)
03674                             argvAdd(&deps, s);
03675                         /*@switchbreak@*/ break;
03676                     case DT_SONAME:
03677                         gotSONAME = 1;
03678                         s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
03679 assert(s != NULL);
03680                         /* Add next provide dependency. */
03681                         buf[0] = '\0';
03682 
03683                         if (!skipP) {
03684                             ds = rpmdsSingle(RPMTAG_PROVIDENAME,
03685                                     sonameDep(buf, s, isElf64, 1, isuClibc),
03686                                     "", RPMSENSE_FIND_PROVIDES);
03687                             xx = add(context, ds);
03688                             (void)rpmdsFree(ds);
03689                             ds = NULL;
03690                         }
03691                         /*@switchbreak@*/ break;
03692                     }
03693                 }
03694             }
03695             /*@switchbreak@*/ break;
03696         }
03697     }
03698     /*@=uniondef @*/
03699 
03700 exit:
03701     if (gotSONAME && !skipR) {
03702         for (i = 0, cnt = argvCount(deps); i < cnt; i++) {
03703             if (deps[i][0] == 'l' && deps[i][1] == 'd')
03704                 continue;
03705             ds = rpmdsSingle(RPMTAG_REQUIRENAME,
03706                     sonameDep(buf, deps[i], isElf64, 1, isuClibc),
03707                     "", RPMSENSE_FIND_REQUIRES);
03708             xx = add(context, ds);
03709             (void)rpmdsFree(ds);
03710             ds = NULL;
03711         }
03712     }
03713 
03714     deps = argvFree(deps);
03715     if (elf) (void) elf_end(elf);
03716     if (fdno > 0)
03717         xx = close(fdno);
03718     return 0;
03719 #else
03720     return -1;
03721 #endif
03722 }
03723 #endif  /* RPM_VENDOR_MANDRIVA */
03724 
03725 #define _SBIN_LDCONFIG_P        "/sbin/ldconfig -p"
03726 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
03727 static const char * _ldconfig_cmd = _SBIN_LDCONFIG_P;
03728 
03729 #define _LD_SO_CACHE    "/etc/ld.so.cache"
03730 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
03731 static const char * _ldconfig_cache = NULL;
03732 
03733 int rpmdsLdconfig(rpmPRCO PRCO, const char * fn)
03734         /*@globals _ldconfig_cmd, _ldconfig_cache @*/
03735         /*@modifies _ldconfig_cmd, _ldconfig_cache @*/
03736 {
03737     char buf[BUFSIZ];
03738     const char *DSOfn;
03739     const char *N, *EVR;
03740     evrFlags Flags = 0;
03741     rpmds ds;
03742     char * f, * fe;
03743     char * g, * ge;
03744     char * t;
03745     FILE * fp = NULL;
03746     int rc = -1;
03747     int xx;
03748 
03749     if (PRCO == NULL)
03750         return -1;
03751 
03752 /*@-modobserver@*/
03753     if (_ldconfig_cmd == NULL) {
03754         _ldconfig_cmd = rpmExpand("%{?_rpmds_ldconfig_cmd}", NULL);
03755         if (!(_ldconfig_cmd != NULL && *_ldconfig_cmd == '/')) {
03756 /*@-observertrans @*/
03757             _ldconfig_cmd = _free(_ldconfig_cmd);
03758 /*@=observertrans @*/
03759             _ldconfig_cmd = xstrdup(_SBIN_LDCONFIG_P);
03760         }
03761     }
03762 
03763     if (_ldconfig_cache == NULL) {
03764         _ldconfig_cache = rpmExpand("%{?_rpmds_ldconfig_cache}", NULL);
03765         /* XXX may need to validate path existence somewhen. */
03766         if (!(_ldconfig_cache != NULL && *_ldconfig_cache == '/')) {
03767 /*@-observertrans @*/
03768             _ldconfig_cache = _free(_ldconfig_cache);
03769 /*@=observertrans @*/
03770             _ldconfig_cache = xstrdup(_LD_SO_CACHE);
03771         }
03772     }
03773 /*@=modobserver@*/
03774 
03775     if (fn == NULL)
03776         fn = _ldconfig_cache;
03777 
03778 if (_rpmds_debug < 0)
03779 fprintf(stderr, "*** rpmdsLdconfig(%p, %s) P %p R %p C %p O %p T %p D %p L %p\n", PRCO, fn, PRCO->Pdsp, PRCO->Rdsp, PRCO->Cdsp, PRCO->Odsp, PRCO->Tdsp, PRCO->Ddsp, PRCO->Ldsp);
03780 
03781     fp = popen(_ldconfig_cmd, "r");
03782     if (fp == NULL)
03783         goto exit;
03784 
03785     while((f = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
03786         EVR = NULL;
03787         /* rtrim on line. */
03788         ge = f + strlen(f);
03789         while (--ge > f && _isspace(*ge))
03790             *ge = '\0';
03791 
03792         /* ltrim on line. */
03793         while (*f && _isspace(*f))
03794             f++;
03795 
03796         /* split on '=>' */
03797         fe = f;
03798         while (*fe && !(fe[0] == '=' && fe[1] == '>'))
03799             fe++;
03800         if (*fe == '\0')
03801             continue;
03802 
03803         /* find the DSO file name. */
03804         DSOfn = fe + 2;
03805 
03806         /* ltrim on DSO file name. */
03807         while (*DSOfn && _isspace(*DSOfn))
03808             DSOfn++;
03809         if (*DSOfn == '\0')
03810             continue;
03811 
03812         /* rtrim from "=>" */
03813         if (fe > f && fe[-1] == ' ') fe[-1] = '\0';
03814         *fe++ = '\0';
03815         *fe++ = '\0';
03816         g = fe;
03817 
03818         /* ltrim on field 2. */
03819         while (*g && _isspace(*g))
03820             g++;
03821         if (*g == '\0')
03822             continue;
03823 
03824         /* split out flags */
03825         for (t = f; *t != '\0'; t++) {
03826             if (!_isspace(*t))
03827                 /*@innercontinue@*/ continue;
03828             *t++ = '\0';
03829             /*@innerbreak@*/ break;
03830         }
03831         /* XXX "libc4" "ELF" "libc5" "libc6" _("unknown") */
03832         /* XXX use flags to generate soname color */
03833         /* ",64bit" ",IA-64" ",x86-64", ",64bit" are color = 2 */
03834         /* ",N32" for mips64/libn32 */
03835 
03836         /* XXX use flags and LDASSUME_KERNEL to skip sonames? */
03837         /* "Linux" "Hurd" "Solaris" "FreeBSD" "kNetBSD" N_("Unknown OS") */
03838         /* ", OS ABI: %s %d.%d.%d" */
03839 
03840         N = f;
03841         if (EVR == NULL)
03842             EVR = "";
03843         Flags |= RPMSENSE_PROBE;
03844         ds = rpmdsSingle(RPMTAG_PROVIDENAME, N, EVR, Flags);
03845         xx = rpmdsMerge(PRCO->Pdsp, ds);
03846         (void)rpmdsFree(ds);
03847         ds = NULL;
03848 
03849         xx = rpmdsELF(DSOfn, 0, rpmdsMergePRCO, PRCO);
03850     }
03851     rc = 0;
03852 
03853 exit:
03854     if (fp != NULL) (void) pclose(fp);
03855     return rc;
03856 }
03857 
03858 
03859 #if defined(__sun)
03860 #define _RLD_SEARCH_PATH        "/lib:/usr/lib"
03861 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
03862 static const char * _rld_search_path = NULL;
03863 
03864 /* search a colon-separated list of directories for shared objects */
03865 int rpmdsRldpath(rpmPRCO PRCO, const char * rldp)
03866         /*@globals _rld_search_path @*/
03867         /*@modifies _rld_search_path @*/
03868 {
03869     char buf[BUFSIZ];
03870     const char *N, *EVR;
03871     evrFlags Flags = 0;
03872     rpmds ds;
03873     const char * f;
03874     const char * g;
03875     int rc = -1;
03876     int xx;
03877     glob_t  gl;
03878     char ** gp;
03879 
03880     if (PRCO == NULL)
03881         return -1;
03882 
03883 /*@-modobserver@*/
03884     if (_rld_search_path == NULL) {
03885         _rld_search_path = rpmExpand("%{?_rpmds_rld_search_path}", NULL);
03886         /* XXX may need to validate path existence somewhen. */
03887         if (!(_rld_search_path != NULL && *_rld_search_path == '/')) {
03888 /*@-observertrans @*/
03889             _rld_search_path = _free(_rld_search_path);
03890 /*@=observertrans @*/
03891             _rld_search_path = xstrdup(_RLD_SEARCH_PATH);
03892         }
03893     }
03894 /*@=modobserver@*/
03895 
03896     if (rldp == NULL)
03897         rldp = _rld_search_path;
03898 
03899 if (_rpmds_debug > 0)
03900 fprintf(stderr, "*** rpmdsRldpath(%p, %s) P %p R %p C %p O %p\n", PRCO, rldp, PRCO->Pdsp, PRCO->Rdsp, PRCO->Cdsp, PRCO->Odsp);
03901 
03902     f = rldp;
03903     /* move through the path, splitting on : */
03904     while (f) {
03905         EVR = NULL;
03906         g = strchr(f, ':');
03907         if (g == NULL) {
03908             strcpy(buf, f);
03909             /* this is the last element, no more :'s */
03910             f = NULL;
03911         } else {
03912             /* copy this chunk to buf */
03913             strncpy(buf, f, g - f + 1);
03914             buf[g-f] = '\0';
03915 
03916             /* get ready for next time through */
03917             f = g + 1;
03918         }
03919 
03920         if ( !(strlen(buf) > 0 && buf[0] == '/') )
03921             continue;
03922 
03923         /* XXX: danger, buffer len */
03924         /* XXX: *.so.* should be configurable via a macro */
03925         strcat(buf, "/*.so.*");
03926 
03927 if (_rpmds_debug > 0)
03928 fprintf(stderr, "*** rpmdsRldpath(%p, %s) globbing %s\n", PRCO, rldp, buf);
03929 
03930         xx = Glob(buf, 0, NULL, &gl);
03931         if (xx)         /* glob error, probably GLOB_NOMATCH */
03932             continue;
03933 
03934 if (_rpmds_debug > 0)
03935 fprintf(stderr, "*** rpmdsRldpath(%p, %s) glob matched %d files\n", PRCO, rldp, gl.gl_pathc);
03936 
03937         gp = gl.gl_pathv;
03938         /* examine each match */
03939         while (gp && *gp) {
03940             const char *DSOfn;
03941             /* XXX: should probably verify that we matched a file */
03942             DSOfn = *gp;
03943             gp++;
03944             if (EVR == NULL)
03945                 EVR = "";
03946 
03947             /* N needs to be basename of DSOfn */
03948             N = DSOfn + strlen(DSOfn);
03949             while (N > DSOfn && *N != '/')
03950                 --N;
03951 
03952             Flags |= RPMSENSE_PROBE;
03953             ds = rpmdsSingle(RPMTAG_PROVIDENAME, N, EVR, Flags);
03954             xx = rpmdsMerge(PRCO->Pdsp, ds);
03955             (void)rpmdsFree(ds);
03956             ds = NULL;
03957 
03958             xx = rpmdsELF(DSOfn, 0, rpmdsMergePRCO, PRCO);
03959         }
03960 /*@-immediatetrans@*/
03961         Globfree(&gl);
03962 /*@=immediatetrans@*/
03963     }
03964     rc = 0;
03965 
03966     return rc;
03967 }
03968 
03969 #define _SOLARIS_CRLE   "/usr/sbin/crle"
03970 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
03971 static const char * _crle_cmd = NULL;
03972 
03973 int rpmdsCrle(rpmPRCO PRCO, /*@unused@*/ const char * fn)
03974         /*@globals _crle_cmd @*/
03975         /*@modifies _crle_cmd @*/
03976 {
03977     char buf[BUFSIZ];
03978     char * f;
03979     char * g, * ge;
03980     FILE * fp = NULL;
03981     int rc = -1;        /* assume failure */
03982     int xx;
03983     int found_dlp = 0;
03984 
03985     if (PRCO == NULL)
03986         return -1;
03987 
03988 /*@-modobserver@*/
03989     if (_crle_cmd == NULL) {
03990         _crle_cmd = rpmExpand("%{?_rpmds_crle_cmd}", NULL);
03991         if (!(_crle_cmd != NULL && *_crle_cmd == '/')) {
03992 /*@-observertrans @*/
03993             _crle_cmd = _free(_crle_cmd);
03994 /*@=observertrans @*/
03995             _crle_cmd = xstrdup(_SOLARIS_CRLE);
03996         }
03997     }
03998 
03999     /* XXX: we rely on _crle_cmd including the -64 arg, if ELF64 */
04000     fp = popen(_crle_cmd, "r");
04001     if (fp == NULL)
04002         return rc;
04003 
04004     /* 
04005      * we want the first line that contains "(ELF):"
04006      * we cannot search for "Default Library Path (ELF):" because that
04007      * changes in non-C locales.
04008      */
04009     while((f = fgets(buf, sizeof(buf), fp)) != NULL) {
04010         if (found_dlp)  /* XXX read all data? */
04011             continue;
04012 
04013         g = strstr(f, "(ELF):");
04014         if (g == NULL)
04015             continue;
04016 
04017         found_dlp = 1;
04018         f = g + (sizeof("(ELF):")-1);
04019         while (_isspace(*f))
04020             f++;
04021 
04022         /* rtrim path */
04023         ge = f + strlen(f);
04024         while (--ge > f && _isspace(*ge))
04025             *ge = '\0';
04026     }
04027     xx = pclose(fp);
04028 
04029     /* we have the loader path, let rpmdsRldpath() do the work */
04030     if (found_dlp)
04031         rc = rpmdsRldpath(PRCO, f);
04032 
04033     return rc;
04034 }
04035 #endif
04036 
04037 int rpmdsUname(rpmds *dsp, const struct utsname * un)
04038 {
04039 /*@observer@*/
04040     static const char * NS = "uname";
04041     struct utsname myun;
04042     int rc = -1;
04043     int xx;
04044 
04045     if (un == NULL) {
04046         xx = uname(&myun);
04047         if (xx != 0)
04048             goto exit;
04049         un = &myun;
04050     }
04051 
04052 /*@-type@*/
04053     /* XXX values need to be checked for EVR (i.e. no '-' character.) */
04054     if (un->sysname != NULL)
04055         rpmdsNSAdd(dsp, NS, "sysname", un->sysname, RPMSENSE_EQUAL);
04056     if (un->nodename != NULL)
04057         rpmdsNSAdd(dsp, NS, "nodename", un->nodename, RPMSENSE_EQUAL);
04058     if (un->release != NULL)
04059         rpmdsNSAdd(dsp, NS, "release", un->release, RPMSENSE_EQUAL);
04060 #if 0   /* XXX has embedded spaces */
04061     if (un->version != NULL)
04062         rpmdsNSAdd(dsp, NS, "version", un->version, RPMSENSE_EQUAL);
04063 #endif
04064     if (un->machine != NULL)
04065         rpmdsNSAdd(dsp, NS, "machine", un->machine, RPMSENSE_EQUAL);
04066 #if defined(__linux__)
04067     if (un->domainname != NULL && strcmp(un->domainname, "(none)"))
04068         rpmdsNSAdd(dsp, NS, "domainname", un->domainname, RPMSENSE_EQUAL);
04069 #endif
04070 /*@=type@*/
04071     rc = 0;
04072 
04073 exit:
04074     return rc;
04075 }
04076 
04077 #define _PERL_PROVIDES  "/usr/bin/find /usr/lib/perl5 | /usr/lib/rpm/perl.prov"
04078 /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
04079 static const char * _perldeps_cmd = NULL;
04080 
04081 int rpmdsPipe(rpmds * dsp, rpmTag tagN, const char * cmd)
04082         /*@globals _perldeps_cmd @*/
04083         /*@modifies _perldeps_cmd @*/
04084 {
04085     char buf[BUFSIZ];
04086     const char *N, *EVR;
04087     evrFlags Flags = 0;
04088     rpmds ds;
04089     char * f, * fe;
04090     char * g, * ge;
04091     FILE * fp = NULL;
04092     const char * fn = "pipe";
04093     int rc = -1;
04094     int cmdprinted;
04095     int ln;
04096     int xx;
04097 
04098 /*@-modobserver@*/
04099     if (_perldeps_cmd == NULL) {
04100         _perldeps_cmd = rpmExpand("%{?_rpmds_perldeps_cmd}", NULL);
04101         /* XXX may need to validate path existence somewhen. */
04102         if (!(_perldeps_cmd != NULL && *_perldeps_cmd == '/')) {
04103 /*@-observertrans @*/
04104             _perldeps_cmd = _free(_perldeps_cmd);
04105 /*@=observertrans @*/
04106             _perldeps_cmd = xstrdup(_PERL_PROVIDES);
04107         }
04108     }
04109 /*@=modobserver@*/
04110 
04111     if (tagN <= 0)
04112         tagN = RPMTAG_PROVIDENAME;
04113     if (cmd == NULL)
04114         cmd = _perldeps_cmd;
04115 
04116     fp = popen(cmd, "r");
04117     if (fp == NULL)
04118         goto exit;
04119 
04120     ln = 0;
04121     cmdprinted = 0;
04122     while((f = fgets(buf, (int)sizeof(buf), fp)) != NULL) {
04123         ln++;
04124 
04125         /* insure a terminator. */
04126         buf[sizeof(buf)-1] = '\0';
04127 
04128         /* ltrim on line. */
04129         while (*f && _isspace(*f))
04130             f++;
04131 
04132         /* skip empty lines and comments */
04133         if (*f == '\0' || *f == '#')
04134             continue;
04135 
04136         /* rtrim on line. */
04137         fe = f + strlen(f);
04138         while (--fe > f && _isspace(*fe))
04139             *fe = '\0';
04140 
04141         /* split on ' '  or comparison operator. */
04142         fe = f;
04143         if (*f == '!') fe++;
04144         while (*fe && !_isspace(*fe) && strchr("!<=>", *fe) == NULL)
04145             fe++;
04146         while (*fe && _isspace(*fe))
04147             *fe++ = '\0';
04148 
04149         if (!(xisalnum(f[0]) || strchr("/_%!", f[0]) != NULL)) {
04150             if (!cmdprinted++)
04151                 fprintf(stderr, _("running \"%s\" pipe command\n"), cmd);
04152             fprintf(stderr, _("%s:%d \"%s\" has invalid name. Skipping ...\n"),
04153                         fn, ln, f);
04154             continue;
04155         }
04156 
04157         N = f;
04158         EVR = NULL;
04159         Flags = 0;
04160 
04161         /* parse for non-path, versioned dependency. */
04162         if (*f != '/' && *fe != '\0') {
04163             /* parse comparison operator */
04164             g = fe;
04165             Flags = rpmEVRflags(fe, (const char **)&g);
04166             if (Flags == 0) {
04167                 if (!cmdprinted++)
04168                     fprintf(stderr, _("running \"%s\" pipe command\n"), cmd),
04169                 fprintf(stderr, _("%s:%d \"%s\" has no comparison operator. Skipping ...\n"),
04170                         fn, ln, fe);
04171                 continue;
04172             }
04173             *fe = '\0';
04174 
04175             /* ltrim on field 2. */
04176             while (*g && _isspace(*g))
04177                 g++;
04178             if (*g == '\0') {
04179                 if (!cmdprinted++)
04180                     fprintf(stderr, _("running \"%s\" pipe command\n"), cmd),
04181                 /* XXX No EVR comparison value found. */
04182                 fprintf(stderr, _("\tline %d: No EVR comparison value found.\n Skipping ..."),
04183                         ln);
04184                 fprintf(stderr, _("%s:%d \"%s\" has no EVR string. Skipping ...\n"),
04185                         fn, ln, f);
04186                 continue;
04187             }
04188 
04189             ge = g + 1;
04190             while (*ge && !_isspace(*ge))
04191                 ge++;
04192 
04193             if (*ge != '\0')
04194                 *ge = '\0';     /* XXX can't happen, line rtrim'ed already. */
04195 
04196             EVR = g;
04197         }
04198 
04199         if (EVR == NULL)
04200             EVR = "";
04201         Flags |= RPMSENSE_PROBE;
04202         ds = rpmdsSingle(tagN, N, EVR, Flags);
04203         xx = rpmdsMerge(dsp, ds);
04204         (void)rpmdsFree(ds);
04205         ds = NULL;
04206     }
04207     rc = 0;
04208 
04209 exit:
04210     if (fp != NULL) (void) pclose(fp);
04211     return rc;
04212 }
04213 
04214 static int rpmdsNAcmp(rpmds A, rpmds B)
04215         /*@*/
04216 {
04217     const char * AN = A->ns.N;
04218     const char * AA = A->ns.A;
04219     const char * BN = B->ns.N;
04220     const char * BA = B->ns.A;
04221     int rc;
04222 
04223     if (!AA && !BA) {
04224         rc = strcmp(AN, BN);
04225     } else if (AA && !BA) {
04226         rc = strncmp(AN, BN, (AA - AN)) || BN[AA - AN];
04227         if (!rc)
04228             rc = strcmp(AA, B->A);
04229     } else if (!AA && BA) {
04230         rc = strncmp(AN, BN, (BA - BN)) || AN[BA - BN];
04231         if (!rc)
04232             rc = strcmp(BA, A->A);
04233     } else {
04234         rc = strcmp(AN, BN);
04235     }
04236     return rc;
04237 }
04238 
04239 /*@unchecked@*/ /*@only@*/ /*@null@*/
04240 const char * evr_tuple_order = NULL;
04241 
04246 /*@observer@*/
04247 static const char * rpmdsEVRorder(void)
04248         /*@globals evr_tuple_order @*/
04249         /*@modifies evr_tuple_order @*/
04250 {
04251     if (evr_tuple_order == NULL) {
04252 /*@-mods@*/
04253         evr_tuple_order = rpmExpand("%{?evr_tuple_order}", NULL);
04254 /*@=mods@*/
04255         if (evr_tuple_order == NULL || evr_tuple_order[0] == '\0')
04256             evr_tuple_order = xstrdup("EVR");
04257     }
04258 assert(evr_tuple_order != NULL && evr_tuple_order[0] != '\0');
04259 /*@-freshtrans@*/
04260     return evr_tuple_order;
04261 /*@=freshtrans@*/
04262 }
04263 
04264 int rpmdsCompare(const rpmds A, const rpmds B)
04265 {
04266     const char *aDepend = (A->DNEVR != NULL ? xstrdup(A->DNEVR+2) : "");
04267     const char *bDepend = (B->DNEVR != NULL ? xstrdup(B->DNEVR+2) : "");
04268     EVR_t a = memset(alloca(sizeof(*a)), 0, sizeof(*a));
04269     EVR_t b = memset(alloca(sizeof(*a)), 0, sizeof(*a));
04270     evrFlags aFlags = A->ns.Flags;
04271     evrFlags bFlags = B->ns.Flags;
04272     int (*EVRcmp) (const char *a, const char *b);
04273     int result = 1;
04274     const char * s;
04275     int sense;
04276     int xx;
04277 
04278 assert((rpmdsFlags(A) & RPMSENSE_SENSEMASK) == A->ns.Flags);
04279 assert((rpmdsFlags(B) & RPMSENSE_SENSEMASK) == B->ns.Flags);
04280     /* Different names (and/or name.arch's) don't overlap. */
04281     if (rpmdsNAcmp(A, B)) {
04282         result = 0;
04283         goto exit;
04284     }
04285 
04286     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
04287 /*@-nullderef@*/
04288     if (!(A->EVR && A->Flags && B->EVR && B->Flags))
04289         goto exit;
04290 
04291     /* Same name. If either A or B is an existence test, always overlap. */
04292     if (!(aFlags && bFlags))
04293         goto exit;
04294 
04295     /* If either EVR is non-existent or empty, always overlap. */
04296     if (!(A->EVR[A->i] && *A->EVR[A->i] && B->EVR[B->i] && *B->EVR[B->i]))
04297         goto exit;
04298 
04299     /* Both AEVR and BEVR exist. */
04300     xx = (A->EVRparse ? A->EVRparse : rpmEVRparse) (A->EVR[A->i], a);
04301     xx = (B->EVRparse ? B->EVRparse : rpmEVRparse) (B->EVR[B->i], b);
04302 
04303     /* If EVRcmp is identical, use that, otherwise use default. */
04304     EVRcmp = (A->EVRcmp && B->EVRcmp && A->EVRcmp == B->EVRcmp)
04305         ? A->EVRcmp : rpmvercmp;
04306 
04307     /* Compare {A,B} [epoch:]version[-release][:distepoch] */
04308     sense = 0;
04309     for (s = rpmdsEVRorder(); *s; s++) {
04310         int ix;
04311         switch ((int)*s) {
04312         default:        continue;       /*@notreached@*//*@switchbreak@*/ break;
04313         case 'E':
04314             ix = RPMEVR_E;
04315             if (a->F[ix] && *a->F[ix] && b->F[ix] && *b->F[ix])
04316                 /*@switchbreak@*/ break;
04317             /* XXX Special handling for missing Epoch: tags hysteria */
04318             if (a->F[ix] && *a->F[ix] && atol(a->F[ix]) > 0) {
04319                 if (!B->nopromote) {
04320                     int lvl = (_rpmds_unspecified_epoch_noise
04321                         ? RPMLOG_WARNING : RPMLOG_DEBUG);
04322                     rpmlog(lvl, _("The \"B\" dependency needs an epoch (assuming same epoch as \"A\")\n\tA = \"%s\"\tB = \"%s\"\n"),
04323                         aDepend, bDepend);
04324                     sense = 0;
04325                 } else
04326                     sense = 1;
04327             } else
04328             if (b->F[ix] && *b->F[ix] && atol(b->F[ix]) > 0)
04329                 sense = -1;
04330             /*@switchbreak@*/ break;
04331         case 'V':       ix = RPMEVR_V;  /*@switchbreak@*/break;
04332         case 'R':       ix = RPMEVR_R;  /*@switchbreak@*/break;
04333         case 'D':       ix = RPMEVR_D;  /*@switchbreak@*/break;
04334         }
04335 #if defined(RPM_VENDOR_MANDRIVA) /* mdvbz#55810 */
04336         if(ix >= RPMEVR_R && (bFlags & (~RPMSENSE_GREATER & RPMSENSE_EQUAL))
04337                                 && *(b->F[ix]) == '\0')
04338                             break;
04339         if (a->F[ix] && b->F[ix])
04340 #else
04341         if (a->F[ix] && *a->F[ix] && b->F[ix] && *b->F[ix])
04342 #endif
04343 /*@i@*/     sense = EVRcmp(a->F[ix], b->F[ix]);
04344         if (sense)
04345             break;
04346     }
04347 
04348     a->str = _free(a->str);
04349     b->str = _free(b->str);
04350 
04351     /* Detect overlap of {A,B} range. */
04352     if (aFlags == RPMSENSE_NOTEQUAL || bFlags == RPMSENSE_NOTEQUAL) {
04353         result = (sense != 0);
04354     } else if (sense < 0 && ((aFlags & RPMSENSE_GREATER) || (bFlags & RPMSENSE_LESS))) {
04355         result = 1;
04356     } else if (sense > 0 && ((aFlags & RPMSENSE_LESS) || (bFlags & RPMSENSE_GREATER))) {
04357         result = 1;
04358     } else if (sense == 0 &&
04359         (((aFlags & RPMSENSE_EQUAL) && (bFlags & RPMSENSE_EQUAL)) ||
04360          ((aFlags & RPMSENSE_LESS) && (bFlags & RPMSENSE_LESS)) ||
04361          ((aFlags & RPMSENSE_GREATER) && (bFlags & RPMSENSE_GREATER)))) {
04362         result = 1;
04363     } else
04364         result = 0;
04365 /*@=nullderef@*/
04366 
04367 exit:
04368     if (_noisy_range_comparison_debug_message)
04369     rpmlog(RPMLOG_DEBUG, D_("  %s    A %s\tB %s\n"),
04370         (result ? _("YES") : _("NO ")), aDepend, bDepend);
04371     aDepend = _free(aDepend);
04372     bDepend = _free(bDepend);
04373     return result;
04374 }
04375 
04376 int rpmdsMatch(const rpmds A, rpmds B)
04377 {
04378     int result = 0;
04379 
04380     /* If A dependency matches any in B, we're done. */
04381     if ((B = rpmdsInit(B)) != NULL)
04382     while (rpmdsNext(B) >= 0)
04383         if ((result = rpmdsCompare(A, B)))
04384             break;
04385     return result;
04386 }
04387 
04388 void rpmdsProblem(rpmps ps, const char * pkgNEVR, const rpmds ds,
04389         const fnpyKey * suggestedKeys, int adding)
04390 {
04391     const char * Name =  rpmdsN(ds);
04392     const char * DNEVR = rpmdsDNEVR(ds);
04393     const char * EVR = rpmdsEVR(ds);
04394     rpmProblemType type;
04395     fnpyKey key;
04396 
04397     if (ps == NULL) return;
04398 
04399     if (Name == NULL) Name = "?N?";
04400     if (EVR == NULL) EVR = "?EVR?";
04401     if (DNEVR == NULL) DNEVR = "? ?N? ?OP? ?EVR?";
04402 
04403     rpmlog(RPMLOG_DEBUG, D_("package %s has unsatisfied %s: %s\n"),
04404             pkgNEVR, ds->Type, DNEVR+2);
04405 
04406     switch ((unsigned)DNEVR[0]) {
04407     case 'C':   type = RPMPROB_CONFLICT;        break;
04408     default:
04409     case 'R':   type = RPMPROB_REQUIRES;        break;
04410     }
04411 
04412     key = (suggestedKeys ? suggestedKeys[0] : NULL);
04413     rpmpsAppend(ps, type, pkgNEVR, key, NULL, NULL, DNEVR, adding);
04414 }
04415 
04416 int rpmdsAnyMatchesDep (const Header h, const rpmds req, int nopromote)
04417 {
04418     int scareMem = 0;
04419     rpmds provides = NULL;
04420     evrFlags reqFlags = req->ns.Flags;
04421     int result = 1;
04422 
04423 assert((rpmdsFlags(req) & RPMSENSE_SENSEMASK) == req->ns.Flags);
04424     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
04425     if (req->EVR == NULL || req->Flags == NULL)
04426         goto exit;
04427 
04428     switch(req->ns.Type) {
04429     default:
04430         /* Primary key retrieve satisfes an existence compare. */
04431         if (!reqFlags || !req->EVR[req->i] || *req->EVR[req->i] == '\0')
04432             goto exit;
04433         /*@fallthrough@*/
04434     case RPMNS_TYPE_ARCH:
04435         break;
04436     }
04437 
04438     /* Get provides information from header */
04439     provides = rpmdsInit(rpmdsNew(h, RPMTAG_PROVIDENAME, scareMem));
04440     if (provides == NULL) {
04441         result = 0;
04442         goto exit;      /* XXX should never happen */
04443     }
04444     if (nopromote)
04445         (void) rpmdsSetNoPromote(provides, nopromote);
04446 
04447     /*
04448      * Rpm prior to 3.0.3 did not have versioned provides.
04449      * If no provides version info is available, match any/all requires
04450      * with same name.
04451      */
04452     if (provides->EVR == NULL)
04453         goto exit;
04454 
04455     /* If any provide matches the require, we're done. */
04456     result = 0;
04457     if (provides != NULL)
04458     while (rpmdsNext(provides) >= 0)
04459         if ((result = rpmdsCompare(provides, req)))
04460             break;
04461 
04462 exit:
04463     (void)rpmdsFree(provides);
04464     provides = NULL;
04465 
04466     return result;
04467 }
04468 
04469 int rpmdsNVRMatchesDep(const Header h, const rpmds req, int nopromote)
04470 {
04471     HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
04472     const char * pkgN, * V, * R;
04473 #ifdef  RPM_VENDOR_MANDRIVA
04474     const char * D;
04475     int gotD = 0;
04476 #endif
04477     rpmuint32_t E;
04478     int gotE = 0;
04479     const char * pkgEVR;
04480     char * t;
04481     evrFlags reqFlags = req->ns.Flags;
04482     evrFlags pkgFlags = RPMSENSE_EQUAL;
04483     int result = 1;
04484     rpmds pkg;
04485     size_t nb;
04486 
04487 assert((rpmdsFlags(req) & RPMSENSE_SENSEMASK) == req->ns.Flags);
04488     /* XXX rpm prior to 3.0.2 did not always supply EVR and Flags. */
04489     if (req->EVR == NULL || req->Flags == NULL)
04490         goto exit;
04491 
04492     if (!(reqFlags && req->EVR[req->i] && *req->EVR[req->i]))
04493         goto exit;
04494 
04495     /* Get package information from header */
04496 /*@-mods@*/
04497     (void) headerNEVRA(h, &pkgN, NULL, &V, &R, NULL);
04498 /*@=mods@*/
04499     /* XXX segfault avoidance */
04500     if (pkgN == NULL)   pkgN = xstrdup("N");
04501     if (V == NULL)      V = xstrdup("V");
04502     if (R == NULL)      R = xstrdup("R");
04503     he->tag = RPMTAG_EPOCH;
04504     gotE = headerGet(h, he, 0);
04505     E = (he->p.ui32p ? he->p.ui32p[0] : 0);
04506     he->p.ptr = _free(he->p.ptr);
04507 
04508 #if defined(RPM_VENDOR_MANDRIVA)
04509     he->tag = RPMTAG_DISTEPOCH;
04510     gotD = headerGet(h, he, 0);
04511     D = (he->p.str ? he->p.str : NULL);
04512 #endif
04513 
04514     nb = 21 + 1 + 1;
04515     if (V) nb += strlen(V);
04516     if (R) nb += strlen(R);
04517 #if defined(RPM_VENDOR_MANDRIVA)
04518     if (gotD) nb += strlen(D) + 1;
04519 #endif
04520     pkgEVR = t = alloca(nb);
04521     *t = '\0';
04522     if (gotE) {
04523         sprintf(t, "%d:", E);
04524         t += strlen(t);
04525     }
04526     t = stpcpy( stpcpy( stpcpy(t, V) , "-") , R);
04527 #if defined(RPM_VENDOR_MANDRIVA)
04528     if (gotD) {
04529         t =  stpcpy( stpcpy( t, ":"), D);
04530         D = _free(D);
04531     }
04532 #endif
04533     V = _free(V);
04534     R = _free(R);
04535 
04536     if ((pkg = rpmdsSingle(RPMTAG_PROVIDENAME, pkgN, pkgEVR, pkgFlags)) != NULL) {
04537         if (nopromote)
04538             (void) rpmdsSetNoPromote(pkg, nopromote);
04539         result = rpmdsCompare(pkg, req);
04540         (void)rpmdsFree(pkg);
04541         pkg = NULL;
04542     }
04543     pkgN = _free(pkgN);
04544 
04545 exit:
04546     return result;
04547 }
04548 
04549 int rpmdsNegateRC(const rpmds ds, int rc)
04550 {
04551     if (ds->ns.str[0] == '!')
04552         rc = (rc == 0);
04553     return rc;
04554 }