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