rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

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