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