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