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