• 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 }

Generated on Fri Dec 3 2010 20:53:36 for rpm by  doxygen 1.7.2