rpm 5.3.7
|
00001 #include "system.h" 00002 00003 #include <stdarg.h> 00004 00005 #if defined(HAVE_SYS_SYSTEMCFG_H) 00006 #include <sys/systemcfg.h> 00007 #else 00008 #define __power_pc() 0 00009 #endif 00010 00011 #define _RPMIOB_INTERNAL /* XXX for rpmiobSlurp */ 00012 #include <rpmio.h> 00013 #include <rpmcb.h> 00014 #define _MIRE_INTERNAL 00015 #include <mire.h> 00016 #include <argv.h> 00017 #include <rpmlua.h> 00018 #include <rpmluaext.h> 00019 #include <rpmmacro.h> 00020 00021 #include <rpmtypes.h> 00022 #include <rpmtag.h> 00023 #define _RPMEVR_INTERNAL 00024 #include <rpmevr.h> 00025 00026 #define _RPMDS_INTERNAL 00027 #include <rpmds.h> 00028 00029 #include <rpmcli.h> 00030 00031 #include <rpmsyck.h> 00032 00033 #include "debug.h" 00034 00035 /*@access miRE@*/ 00036 00037 /*@unchecked@*/ /*@null@*/ 00038 static const char * configTarget = NULL; 00039 00040 /*@observer@*/ /*@unchecked@*/ 00041 static const char * platform = SYSCONFIGDIR "/platform"; 00042 00043 /*@only@*/ /*@relnull@*/ /*@unchecked@*/ 00044 void * platpat = NULL; 00045 /*@unchecked@*/ 00046 int nplatpat = 0; 00047 00048 extern rpmds cpuinfoP; 00049 00050 00051 00057 enum rpm_machtable_e { 00058 RPM_MACHTABLE_INSTARCH = 0, 00059 RPM_MACHTABLE_INSTOS = 1, 00060 RPM_MACHTABLE_BUILDARCH = 2, 00061 RPM_MACHTABLE_BUILDOS = 3 00062 }; 00063 #define RPM_MACHTABLE_COUNT 4 00065 typedef /*@owned@*/ const char * cptr_t; 00066 00067 typedef struct machCacheEntry_s { 00068 const char * name; 00069 int count; 00070 cptr_t * equivs; 00071 int visited; 00072 } * machCacheEntry; 00073 00074 typedef struct machCache_s { 00075 machCacheEntry cache; 00076 int size; 00077 } * machCache; 00078 00079 typedef struct machEquivInfo_s { 00080 const char * name; 00081 int score; 00082 } * machEquivInfo; 00083 00084 typedef struct machEquivTable_s { 00085 int count; 00086 machEquivInfo list; 00087 } * machEquivTable; 00088 00089 typedef struct defaultEntry_s { 00090 /*@owned@*/ /*@null@*/ const char * name; 00091 /*@owned@*/ /*@null@*/ const char * defName; 00092 } * defaultEntry; 00093 00094 typedef struct canonEntry_s { 00095 /*@owned@*/ const char * name; 00096 /*@owned@*/ const char * short_name; 00097 short num; 00098 } * canonEntry; 00099 00100 /* tags are 'key'canon, 'key'translate, 'key'compat 00101 * 00102 * for giggles, 'key'_canon, 'key'_compat, and 'key'_canon will also work 00103 */ 00104 typedef struct tableType_s { 00105 /*@observer@*/ const char * const key; 00106 const int hasCanon; 00107 const int hasTranslate; 00108 struct machEquivTable_s equiv; 00109 struct machCache_s cache; 00110 defaultEntry defaults; 00111 canonEntry canons; 00112 int defaultsLength; 00113 int canonsLength; 00114 } * tableType; 00115 00116 /*@-fullinitblock@*/ 00117 /*@unchecked@*/ 00118 static struct tableType_s tables[RPM_MACHTABLE_COUNT] = { 00119 { "arch", 1, 0 }, 00120 { "os", 1, 0 }, 00121 { "buildarch", 0, 1 }, 00122 { "buildos", 0, 1 } 00123 }; 00124 /*@=fullinitblock@*/ 00125 00126 #define OS 0 00127 #define ARCH 1 00128 00129 /*@unchecked@*/ 00130 static cptr_t current[2]; 00131 00132 /*@unchecked@*/ 00133 static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH }; 00134 00135 /*@unchecked@*/ 00136 static int defaultsInitialized = 0; 00137 00138 /* prototypes */ 00139 static void rpmRebuildTargetVars(/*@null@*/ const char **target, /*@null@*/ const char ** canontarget) 00140 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00141 /*@modifies *canontarget, rpmGlobalMacroContext, 00142 fileSystem, internalState @*/; 00143 00144 static /*@observer@*/ /*@null@*/ machCacheEntry 00145 machCacheFindEntry(const machCache cache, const char * key) 00146 /*@*/ 00147 { 00148 int i; 00149 00150 for (i = 0; i < cache->size; i++) 00151 if (!strcmp(cache->cache[i].name, key)) return cache->cache + i; 00152 00153 return NULL; 00154 } 00155 00156 static void machAddEquiv(machEquivTable table, const char * name, 00157 int distance) 00158 /*@modifies table->list, table->count @*/ 00159 { 00160 machEquivInfo equiv; 00161 00162 { int i; 00163 equiv = NULL; 00164 for (i = 0; i < table->count; i++) { 00165 if (xstrcasecmp(table->list[i].name, name)) 00166 continue; 00167 equiv = table->list + i; 00168 break; 00169 } 00170 } 00171 00172 if (!equiv) { 00173 if (table->count) 00174 table->list = xrealloc(table->list, (table->count + 1) 00175 * sizeof(*table->list)); 00176 else 00177 table->list = xmalloc(sizeof(*table->list)); 00178 00179 table->list[table->count].name = xstrdup(name); 00180 table->list[table->count++].score = distance; 00181 } 00182 } 00183 00184 static void machCacheEntryVisit(machCache cache, 00185 machEquivTable table, const char * name, int distance) 00186 /*@modifies table->list, table->count @*/ 00187 { 00188 machCacheEntry entry; 00189 int i; 00190 00191 entry = machCacheFindEntry(cache, name); 00192 if (!entry || entry->visited) return; 00193 00194 entry->visited = 1; 00195 00196 for (i = 0; i < entry->count; i++) { 00197 machAddEquiv(table, entry->equivs[i], distance); 00198 } 00199 00200 for (i = 0; i < entry->count; i++) { 00201 machCacheEntryVisit(cache, table, entry->equivs[i], distance + 1); 00202 } 00203 } 00204 00205 static void rebuildCompatTables(int type, const char * name) 00206 /*@globals tables, internalState @*/ 00207 /*@modifies tables, internalState @*/ 00208 { 00209 machCache cache = &tables[currTables[type]].cache; 00210 machEquivTable table = &tables[currTables[type]].equiv; 00211 const char * key = name; 00212 int i; 00213 00214 for (i = 0; i < cache->size; i++) 00215 cache->cache[i].visited = 0; 00216 00217 while (table->count > 0) { 00218 --table->count; 00219 table->list[table->count].name = _free(table->list[table->count].name); 00220 } 00221 table->count = 0; 00222 table->list = _free(table->list); 00223 00224 /* 00225 * We have a general graph built using strings instead of pointers. 00226 * Yuck. We have to start at a point at traverse it, remembering how 00227 * far away everything is. 00228 */ 00229 /*@-nullstate@*/ /* FIX: table->list may be NULL. */ 00230 machAddEquiv(table, key, 1); 00231 machCacheEntryVisit(cache, table, key, 2); 00232 return; 00233 /*@=nullstate@*/ 00234 } 00235 00236 static /*@null@*/ canonEntry lookupInCanonTable(const char * name, 00237 const canonEntry table, int tableLen) 00238 /*@*/ 00239 { 00240 while (tableLen) { 00241 tableLen--; 00242 if (strcmp(name, table[tableLen].name)) 00243 continue; 00244 /*@-immediatetrans -retalias@*/ 00245 return &(table[tableLen]); 00246 /*@=immediatetrans =retalias@*/ 00247 } 00248 00249 return NULL; 00250 } 00251 00252 static /*@observer@*/ /*@null@*/ 00253 const char * lookupInDefaultTable(const char * name, 00254 const defaultEntry table, int tableLen) 00255 /*@*/ 00256 { 00257 while (tableLen) { 00258 tableLen--; 00259 if (table[tableLen].name && !strcmp(name, table[tableLen].name)) 00260 return table[tableLen].defName; 00261 } 00262 00263 return name; 00264 } 00265 00266 static void addMacroDefault(const char * macroname, 00267 const char * val, /*@null@*/ const char * body) 00268 /*@globals rpmGlobalMacroContext, internalState @*/ 00269 /*@modifies rpmGlobalMacroContext, internalState @*/ 00270 { 00271 if (body == NULL) 00272 body = val; 00273 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT); 00274 } 00275 00276 static void setPathDefault(const char * macroname, const char * subdir) 00277 /*@globals rpmGlobalMacroContext, internalState @*/ 00278 /*@modifies rpmGlobalMacroContext, internalState @*/ 00279 { 00280 if (macroname != NULL) { 00281 #define _TOPDIRMACRO "%{_topdir}/" 00282 char *body = alloca(sizeof(_TOPDIRMACRO) + strlen(subdir)); 00283 strcpy(body, _TOPDIRMACRO); 00284 strcat(body, subdir); 00285 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT); 00286 #undef _TOPDIRMACRO 00287 } 00288 } 00289 00290 /*@observer@*/ /*@unchecked@*/ 00291 static const char * ___build_pre = "\n\ 00292 RPM_SOURCE_DIR=\"%{_sourcedir}\"\n\ 00293 RPM_BUILD_DIR=\"%{_builddir}\"\n\ 00294 RPM_OPT_FLAGS=\"%{optflags}\"\n\ 00295 RPM_ARCH=\"%{_arch}\"\n\ 00296 RPM_OS=\"%{_os}\"\n\ 00297 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\n\ 00298 RPM_DOC_DIR=\"%{_docdir}\"\n\ 00299 export RPM_DOC_DIR\n\ 00300 RPM_PACKAGE_NAME=\"%{name}\"\n\ 00301 RPM_PACKAGE_VERSION=\"%{version}\"\n\ 00302 RPM_PACKAGE_RELEASE=\"%{release}\"\n\ 00303 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\n\ 00304 %{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\n\ 00305 export RPM_BUILD_ROOT\n}\ 00306 "; 00307 00308 #if defined(RPM_VENDOR_WINDRIVER) 00309 /*@unchecked@*/ 00310 extern const char * __usrlibrpm; 00311 /*@unchecked@*/ 00312 extern const char * __etcrpm; 00313 #endif 00314 00315 static void setDefaults(void) 00316 /*@globals rpmGlobalMacroContext, internalState @*/ 00317 /*@modifies rpmGlobalMacroContext, internalState @*/ 00318 { 00319 00320 #if defined(RPM_VENDOR_WINDRIVER) 00321 addMacro(NULL, "_usrlibrpm", NULL, __usrlibrpm, RMIL_DEFAULT); 00322 addMacro(NULL, "_etcrpm", NULL, __etcrpm, RMIL_DEFAULT); 00323 addMacro(NULL, "_vendor", NULL, "%{?_host_vendor}%{!?_host_vendor:wrs}", RMIL_DEFAULT); 00324 #endif 00325 00326 addMacro(NULL, "_usr", NULL, USRPREFIX, RMIL_DEFAULT); 00327 addMacro(NULL, "_var", NULL, VARPREFIX, RMIL_DEFAULT); 00328 addMacro(NULL, "_prefix", NULL, "%{_usr}", RMIL_DEFAULT); 00329 00330 addMacro(NULL, "___build_pre", NULL, ___build_pre, RMIL_DEFAULT); 00331 00332 addMacroDefault("_topdir", 00333 "%{_usr}/src/rpm", NULL); 00334 addMacroDefault("_tmppath", 00335 "%{_var}/tmp", NULL); 00336 addMacroDefault("_dbpath", 00337 "%{_var}/lib/rpm", NULL); 00338 addMacroDefault("_defaultdocdir", 00339 "%{_usr}/share/doc", NULL); 00340 00341 addMacroDefault("_rpmfilename", 00342 "%%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm",NULL); 00343 00344 addMacroDefault("optflags", 00345 "-O2 -g", NULL); 00346 addMacroDefault("sigtype", 00347 "none", NULL); 00348 addMacroDefault("_buildshell", 00349 "/bin/sh", NULL); 00350 00351 setPathDefault("_builddir", "BUILD"); 00352 setPathDefault("_rpmdir", "RPMS"); 00353 setPathDefault("_srcrpmdir", "SRPMS"); 00354 setPathDefault("_sourcedir", "SOURCES"); 00355 setPathDefault("_specdir", "SPECS"); 00356 00357 } 00358 00359 typedef struct cpu_vendor_os_gnu { 00360 /*@owned@*/ 00361 const char * str; 00362 /*@observer@*/ 00363 const char * cpu; 00364 /*@observer@*/ 00365 const char * vendor; 00366 /*@observer@*/ 00367 const char * os; 00368 /*@observer@*/ 00369 const char * gnu; 00370 } * CVOG_t; 00371 00374 static int parseCVOG(const char * str, CVOG_t *cvogp) 00375 /*@modifies *cvogp @*/ 00376 { 00377 CVOG_t cvog = xcalloc(1, sizeof(*cvog)); 00378 char * p, * pe; 00379 00380 cvog->str = p = xstrdup(str); 00381 pe = p + strlen(p); 00382 while (pe-- > p && isspace(*pe)) 00383 *pe = '\0'; 00384 00385 cvog->cpu = p; 00386 cvog->vendor = "unknown"; 00387 cvog->os = "unknown"; 00388 cvog->gnu = ""; 00389 while (*p && !(*p == '-' || isspace(*p))) 00390 p++; 00391 if (*p != '\0') *p++ = '\0'; 00392 00393 cvog->vendor = p; 00394 while (*p && !(*p == '-' || isspace(*p))) 00395 p++; 00396 if (*p != '-') { 00397 if (*p != '\0') *p++ = '\0'; 00398 cvog->os = cvog->vendor; 00399 cvog->vendor = "unknown"; 00400 } else { 00401 if (*p != '\0') *p++ = '\0'; 00402 00403 cvog->os = p; 00404 while (*p && !(*p == '-' || isspace(*p))) 00405 p++; 00406 if (*p == '-') { 00407 *p++ = '\0'; 00408 00409 cvog->gnu = p; 00410 while (*p && !(*p == '-' || isspace(*p))) 00411 p++; 00412 } 00413 if (*p != '\0') *p++ = '\0'; 00414 } 00415 00416 if (cvogp) 00417 *cvogp = cvog; 00418 else { 00419 cvog->str = _free(cvog->str); 00420 cvog = _free(cvog); 00421 } 00422 return 0; 00423 } 00424 00430 /*@-onlytrans@*/ /* XXX miRE array, not refcounted. */ 00431 static rpmRC rpmPlatform(const char * platform) 00432 /*@globals nplatpat, platpat, 00433 rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00434 /*@modifies nplatpat, platpat, 00435 rpmGlobalMacroContext, fileSystem, internalState @*/ 00436 { 00437 CVOG_t cvog = NULL; 00438 rpmiob iob = NULL; 00439 int init_platform = 0; 00440 miRE mi_re = NULL; 00441 int mi_nre = 0; 00442 char * p, * pe; 00443 rpmRC rc; 00444 int xx; 00445 00446 rc = rpmiobSlurp(platform, &iob); 00447 00448 if (rc || iob == NULL) { 00449 rc = RPMRC_FAIL; 00450 goto exit; 00451 } 00452 00453 p = (char *)iob->b; 00454 for (pe = p; p && *p; p = pe) { 00455 pe = strchr(p, '\n'); 00456 if (pe) 00457 *pe++ = '\0'; 00458 00459 while (*p && xisspace(*p)) 00460 p++; 00461 if (*p == '\0' || *p == '#') 00462 continue; 00463 00464 if (init_platform) { 00465 char * t = p + strlen(p); 00466 while (--t > p && xisspace(*t)) 00467 *t = '\0'; 00468 if (t > p) { 00469 xx = mireAppend(RPMMIRE_REGEX, 0, p, NULL, &mi_re, &mi_nre); 00470 } 00471 continue; 00472 } 00473 00474 if (!parseCVOG(p, &cvog) && cvog != NULL) { 00475 addMacro(NULL, "_host_cpu", NULL, cvog->cpu, -1); 00476 addMacro(NULL, "_host_vendor", NULL, cvog->vendor, -1); 00477 addMacro(NULL, "_host_os", NULL, cvog->os, -1); 00478 } 00479 00480 #if defined(RPM_VENDOR_OPENPKG) /* explicit-platform */ 00481 /* do not use vendor and GNU attribution */ 00482 p = rpmExpand("%{_host_cpu}-%{_host_os}", NULL); 00483 #else 00484 p = rpmExpand("%{_host_cpu}-%{_host_vendor}-%{_host_os}", 00485 (cvog && *cvog->gnu ? "-" : NULL), 00486 (cvog ? cvog->gnu : NULL), NULL); 00487 #endif 00488 xx = mireAppend(RPMMIRE_STRCMP, 0, p, NULL, &mi_re, &mi_nre); 00489 p = _free(p); 00490 00491 init_platform++; 00492 } 00493 rc = (init_platform ? RPMRC_OK : RPMRC_FAIL); 00494 00495 exit: 00496 if (cvog) { 00497 cvog->str = _free(cvog->str); 00498 cvog = _free(cvog); 00499 } 00500 iob = rpmiobFree(iob); 00501 if (rc == RPMRC_OK) { 00502 platpat = mireFreeAll(platpat, nplatpat); 00503 platpat = mi_re; 00504 nplatpat = mi_nre; 00505 } 00506 return rc; 00507 } 00508 /*@=onlytrans@*/ 00509 00510 #if defined(WITH_CPUINFO) && defined(WITH_SYCK) 00511 static inline int rpmCpuinfoMatch(const char * feature, const char * EVR, rpmds cpuinfo) 00512 { 00513 rpmds cpufeature = rpmdsSingle(RPMTAG_REQUIRENAME, feature, EVR, RPMSENSE_PROBE); 00514 int ret = rpmdsMatch(cpufeature, cpuinfo); 00515 00516 (void)rpmdsFree(cpufeature); 00517 cpufeature = NULL; 00518 return ret; 00519 } 00520 00521 static rpmRC rpmCpuinfo(void) 00522 { 00523 rpmRC rc = RPMRC_FAIL; 00524 const char *cpu, *_cpuinfo_path; 00525 miRE mi_re = NULL; 00526 int mi_nre = 0, xx, i; 00527 CVOG_t cvog = NULL; 00528 struct stat st; 00529 char *yaml; 00530 rpmsyck_node *tmp, node; 00531 rpmSyck cpuinfoYaml; 00532 FD_t fd; 00533 00534 _cpuinfo_path = rpmGetPath("%{?_rpmhome}%{!?_rpmhome:" USRLIBRPM "}/cpuinfo.yaml", NULL); 00535 if(Stat(_cpuinfo_path, &st)) 00536 return rc; 00537 00538 fd = Fopen(_cpuinfo_path, "r"); 00539 _cpuinfo_path = _free(_cpuinfo_path); 00540 yaml = xcalloc(st.st_size+1, 1); 00541 Fread(yaml, 1, st.st_size, fd); 00542 Fclose(fd); 00543 00544 xx = rpmdsCpuinfo(&cpuinfoP, NULL); 00545 cpuinfoYaml = rpmSyckLoad(yaml); 00546 yaml = _free(yaml); 00547 htGetEntry(cpuinfoYaml->firstNode->value.map, "cpuinfo", &tmp, NULL, NULL); 00548 node = tmp[0]->value.seq; 00549 00550 /* TODO: cleanup.. */ 00551 for(i = 0; node[i].type != T_END; i++) { 00552 if(node[i].type == T_MAP) { 00553 rpmsyck_node *tmp; 00554 if(htHasEntry(node[i].value.map, "Family")) { 00555 htGetEntry(node[i].value.map, "Family", &tmp, NULL, NULL); 00556 const char *family = tmp[0]->value.key; 00557 int j; 00558 hashTable cpus = NULL; 00559 if(rpmCpuinfoMatch(family, "", cpuinfoP)) { 00560 if(htHasEntry(node[i].value.map, "Arch")) { 00561 htGetEntry(node[i].value.map, "Arch", &tmp, NULL, NULL); 00562 rpmsyck_node arch = tmp[0]->value.seq; 00563 for(j = 0; arch[j].type != T_END; j++); 00564 cpus = htCreate(j*2, 0, 0, NULL, NULL); 00565 for(j = 0; arch[j].type != T_END; j++) { 00566 if(htHasEntry(arch[j].value.map, "Extends")) { 00567 if(htGetEntry(arch[j].value.map, "Extends", &tmp, NULL, NULL) && 00568 tmp[0]->type == T_STR && !htHasEntry(cpus, tmp[0]->value.key)) 00569 continue; 00570 } 00571 if(htHasEntry(arch[j].value.map, "Features")) { 00572 htGetEntry(arch[j].value.map, "Features", &tmp, NULL, NULL); 00573 rpmsyck_node features = tmp[0]->value.seq; 00574 int k, match = 0; 00575 for(k = 0; features[k].type != T_END; k++) 00576 if(features[k].type == T_STR && !(match = rpmCpuinfoMatch(features[k].value.key, "", cpuinfoP))) break; 00577 if(!match) continue; 00578 } 00579 if(htHasEntry(arch[j].value.map, "Name")) { 00580 htGetEntry(arch[j].value.map, "Name", &tmp, NULL, NULL); 00581 if(tmp[0]->type != T_STR) continue; 00582 const char *name = tmp[0]->value.key; 00583 rpmsyck_node alias = NULL; 00584 if(htHasEntry(arch[j].value.map, "Alias")) { 00585 htGetEntry(arch[j].value.map, "Alias", &tmp, NULL, NULL); 00586 alias = tmp[0]->value.seq; 00587 } 00588 htAddEntry(cpus, name, alias); 00589 } 00590 } 00591 } 00592 if(htHasEntry(node[i].value.map, "Priority")) { 00593 htGetEntry(node[i].value.map, "Priority", &tmp, NULL, NULL); 00594 rpmsyck_node priority = tmp[0]->value.seq; 00595 int j; 00596 for(j = 0; priority[j].type != T_END; j++) 00597 if(htHasEntry(cpus, priority[j].value.key)) { 00598 xx = mireAppend(RPMMIRE_REGEX, 0, priority[j].value.key, NULL, &mi_re, &mi_nre); 00599 htGetEntry(cpus, priority[j].value.key, &tmp, NULL, NULL); 00600 if(tmp[0]) { 00601 rpmsyck_node alias = tmp[0]; 00602 int k; 00603 for(k = 0; alias[k].type != T_END; k++) 00604 xx = mireAppend(RPMMIRE_REGEX, 0, alias[k].value.key, NULL, &mi_re, &mi_nre); 00605 } 00606 } 00607 } 00608 } 00609 if(cpus) cpus = htFree(cpus); 00610 } 00611 } 00612 } 00613 00614 cpuinfoYaml = rpmSyckFree(cpuinfoYaml); 00615 00616 xx = mireAppend(RPMMIRE_REGEX, 0, "noarch", NULL, &mi_re, &mi_nre); 00617 00618 cpu = mi_re[0].pattern; 00619 if(cpu != NULL) 00620 { 00621 if (!parseCVOG(cpu, &cvog) && cvog != NULL) { 00622 addMacro(NULL, "_host_cpu", NULL, cvog->cpu, -1); 00623 addMacro(NULL, "_host_vendor", NULL, cvog->vendor, -1); 00624 addMacro(NULL, "_host_os", NULL, cvog->os, -1); 00625 } 00626 if (cvog) { 00627 cvog->str = _free(cvog->str); 00628 cvog = _free(cvog); 00629 } 00630 00631 rc = RPMRC_OK; 00632 if (rc == RPMRC_OK) { 00633 platpat = mireFreeAll(platpat, nplatpat); 00634 platpat = mi_re; 00635 nplatpat = mi_nre; 00636 } 00637 00638 } 00639 return rc; 00640 } 00641 #endif 00642 00643 /*@-onlytrans@*/ /* XXX miRE array, not refcounted. */ 00644 int rpmPlatformScore(const char * platform, void * mi_re, int mi_nre) 00645 { 00646 miRE mire; 00647 int i; 00648 00649 if (mi_re == NULL) { 00650 mi_re = platpat; 00651 mi_nre = nplatpat; 00652 } 00653 00654 if ((mire = mi_re) != NULL) 00655 for (i = 0; i < mi_nre; i++) { 00656 if (mireRegexec(mire + i, platform, 0) >= 0) 00657 return (i + 1); 00658 } 00659 return 0; 00660 } 00661 /*@=onlytrans@*/ 00662 00665 static void defaultMachine(/*@out@*/ const char ** arch, 00666 /*@out@*/ const char ** os) 00667 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00668 /*@modifies *arch, *os, rpmGlobalMacroContext, fileSystem, internalState @*/ 00669 { 00670 #if defined(RPM_VENDOR_OPENPKG) /* larger-utsname */ 00671 /* utsname fields on some platforms (like HP-UX) are very small 00672 (just about 8 characters). This is too small for OpenPKG, so cheat! */ 00673 static struct utsname un_real; 00674 static struct { 00675 char sysname[32]; 00676 char nodename[32]; 00677 char release[32]; 00678 char version[32]; 00679 char machine[32]; 00680 } un; 00681 #else 00682 static struct utsname un; 00683 #endif 00684 static int gotDefaults = 0; 00685 int rc; 00686 00687 while (!gotDefaults) { 00688 #if defined(RPM_VENDOR_WINDRIVER) 00689 const char * _platform = rpmGetPath(__etcrpm, "/platform", NULL); 00690 #else 00691 const char * _platform = platform; 00692 #endif 00693 CVOG_t cvog = NULL; 00694 #if defined(RPM_VENDOR_OPENPKG) /* larger-utsname */ 00695 const char *cp; 00696 #endif 00697 #if defined(RPM_VENDOR_OPENPKG) /* larger-utsname */ 00698 /* utsname fields on some platforms (like HP-UX) are very small 00699 (just about 8 characters). This is too small for OpenPKG, so cheat! */ 00700 rc = uname(&un_real); 00701 strncpy(un.sysname, un_real.sysname, sizeof(un.sysname)); un.sysname [sizeof(un.sysname) -1] = '\0'; 00702 strncpy(un.nodename, un_real.nodename, sizeof(un.nodename)); un.nodename[sizeof(un.nodename)-1] = '\0'; 00703 strncpy(un.release, un_real.release, sizeof(un.release)); un.release [sizeof(un.release) -1] = '\0'; 00704 strncpy(un.version, un_real.version, sizeof(un.version)); un.version [sizeof(un.version) -1] = '\0'; 00705 strncpy(un.machine, un_real.machine, sizeof(un.machine)); un.machine [sizeof(un.machine) -1] = '\0'; 00706 #else 00707 rc = uname(&un); 00708 #endif 00709 if (rc < 0) return; 00710 00711 #if defined(RPM_VENDOR_OPENPKG) /* platform-major-minor-only */ 00712 /* Reduce the platform version to major and minor version numbers */ 00713 { 00714 char *cp; 00715 char *cpR; 00716 int n; 00717 cpR = un.release; 00718 if ((n = strcspn(cpR, "0123456789")) > 0) 00719 cpR += n; 00720 if ((n = strspn(cpR, "0123456789.")) > 0) { 00721 /* terminate after "N.N.N...." prefix */ 00722 cpR[n] = '\0'; 00723 /* shorten to "N.N" if longer */ 00724 if ((cp = strchr(cpR, '.')) != NULL) { 00725 if ((cp = strchr(cp+1, '.')) != NULL) 00726 *cp = '\0'; 00727 } 00728 strcat(un.sysname, cpR); 00729 } 00730 /* fix up machine hardware name containing white-space as it 00731 happens to be on Power Macs running MacOS X */ 00732 if (!strncmp(un.machine, "Power Macintosh", 15)) 00733 sprintf(un.machine, "powerpc"); 00734 } 00735 #endif 00736 00737 if (!strncmp(un.machine, "Power Macintosh", 15)) { 00738 sprintf(un.machine, "ppc"); 00739 } 00740 00741 #if defined(RPM_VENDOR_OPENPKG) /* explicit-platform */ 00742 /* allow the path to the "platforms" file be overridden under run-time */ 00743 cp = rpmExpand("%{?__platform}", NULL); 00744 if (cp == NULL || cp[0] == '\0') 00745 cp = _platform; 00746 if (rpmPlatform(cp) == RPMRC_OK) { 00747 #elif defined(WITH_CPUINFO) && defined(WITH_SYCK) 00748 if (rpmPlatform(_platform) == RPMRC_OK || rpmCpuinfo() == RPMRC_OK) 00749 #else 00750 if (rpmPlatform(_platform) == RPMRC_OK) 00751 #endif 00752 { 00753 const char * s; 00754 gotDefaults = 1; 00755 s = rpmExpand("%{?_host_cpu}", NULL); 00756 if (s && *s != '\0') { 00757 strncpy(un.machine, s, sizeof(un.machine)); 00758 un.machine[sizeof(un.machine)-1] = '\0'; 00759 } 00760 s = _free(s); 00761 s = rpmExpand("%{?_host_os}", NULL); 00762 if (s && *s != '\0') { 00763 strncpy(un.sysname, s, sizeof(un.sysname)); 00764 un.sysname[sizeof(un.sysname)-1] = '\0'; 00765 } 00766 s = _free(s); 00767 } 00768 00769 #if defined(RPM_VENDOR_OPENPKG) /* explicit-platform */ 00770 /* cleanup after above processing */ 00771 if (cp != NULL && cp != _platform) 00772 cp = _free(cp); 00773 #endif 00774 #if defined(RPM_VENDOR_WINDRIVER) 00775 _platform = _free(_platform); 00776 #endif 00777 00778 if (configTarget && !parseCVOG(configTarget, &cvog) && cvog != NULL) { 00779 gotDefaults = 1; 00780 if (cvog->cpu && cvog->cpu[0] != '\0') { 00781 strncpy(un.machine, cvog->cpu, sizeof(un.machine)); 00782 un.machine[sizeof(un.machine)-1] = '\0'; 00783 } 00784 if (cvog->os && cvog->os[0] != '\0') { 00785 strncpy(un.sysname, cvog->os, sizeof(un.sysname)); 00786 un.sysname[sizeof(un.sysname)-1] = '\0'; 00787 } 00788 cvog->str = _free(cvog->str); 00789 cvog = _free(cvog); 00790 } 00791 if (gotDefaults) 00792 break; 00793 gotDefaults = 1; 00794 break; 00795 } 00796 00797 if (arch) *arch = un.machine; 00798 if (os) *os = un.sysname; 00799 } 00800 00808 static void rpmSetTables(int archTable, int osTable) 00809 /*@globals currTables, rpmGlobalMacroContext, h_errno, 00810 fileSystem, internalState @*/ 00811 /*@modifies currTables, rpmGlobalMacroContext, 00812 fileSystem, internalState @*/ 00813 { 00814 const char * arch, * os; 00815 00816 defaultMachine(&arch, &os); 00817 00818 if (currTables[ARCH] != archTable) { 00819 currTables[ARCH] = archTable; 00820 rebuildCompatTables(ARCH, arch); 00821 } 00822 00823 if (currTables[OS] != osTable) { 00824 currTables[OS] = osTable; 00825 rebuildCompatTables(OS, os); 00826 } 00827 } 00828 00829 static void rpmSetMachine(const char * arch, const char * os) 00830 /*@globals current, rpmGlobalMacroContext, h_errno, 00831 fileSystem, internalState @*/ 00832 /*@modifies current, rpmGlobalMacroContext, 00833 fileSystem, internalState @*/ 00834 { 00835 if (arch == NULL) { 00836 /*@i@*/ defaultMachine(&arch, NULL); 00837 if (tables[currTables[ARCH]].hasTranslate) 00838 arch = lookupInDefaultTable(arch, 00839 tables[currTables[ARCH]].defaults, 00840 tables[currTables[ARCH]].defaultsLength); 00841 } 00842 assert(arch != NULL); 00843 00844 if (os == NULL) { 00845 /*@i@*/ defaultMachine(NULL, &os); 00846 if (tables[currTables[OS]].hasTranslate) 00847 os = lookupInDefaultTable(os, 00848 tables[currTables[OS]].defaults, 00849 tables[currTables[OS]].defaultsLength); 00850 } 00851 assert(os != NULL); 00852 00853 00854 if (!current[ARCH] || strcmp(arch, current[ARCH])) { 00855 current[ARCH] = _free(current[ARCH]); 00856 current[ARCH] = xstrdup(arch); 00857 rebuildCompatTables(ARCH, arch); 00858 } 00859 00860 if (!current[OS] || strcmp(os, current[OS])) { 00861 char * t = xstrdup(os); 00862 current[OS] = _free(current[OS]); 00863 if (!strcmp(t, "linux")) 00864 *t = 'L'; 00865 current[OS] = t; 00866 rebuildCompatTables(OS, os); 00867 } 00868 } 00869 00870 static void getMachineInfo(int type, /*@null@*/ /*@out@*/ const char ** name, 00871 /*@null@*/ /*@out@*/int * num) 00872 /*@modifies *name, *num @*/ 00873 { 00874 canonEntry canon; 00875 int which = currTables[type]; 00876 00877 /* use the normal canon tables, even if we're looking up build stuff */ 00878 if (which >= 2) which -= 2; 00879 00880 canon = lookupInCanonTable(current[type], 00881 tables[which].canons, 00882 tables[which].canonsLength); 00883 00884 if (canon) { 00885 if (num) *num = canon->num; 00886 if (name) *name = canon->short_name; 00887 } else { 00888 if (num) *num = 255; 00889 #if defined(WITH_CPUINFO) 00890 if (name) { 00891 if(type == ARCH) { 00892 int i, j, n; 00893 ARGV_t archs = NULL; 00894 char *pref = rpmExpand("%{?_prefer_target_cpu}", NULL); 00895 00896 (void) argvSplit(&archs, pref, " "); 00897 for(i = 0, n = argvCount(archs); (i < n && !*name); i++) 00898 if((j = rpmPlatformScore(archs[i], platpat, nplatpat)) > 0) 00899 *name = ((miRE)platpat)[j-1].pattern; 00900 00901 archs = argvFree(archs); 00902 pref = _free(pref); 00903 } 00904 if(!*name) *name = current[type]; 00905 } 00906 #else 00907 if (name) *name = current[type]; 00908 #endif 00909 } 00910 } 00911 00912 static void rpmRebuildTargetVars(const char ** target, const char ** canontarget) 00913 { 00914 00915 char *ca = NULL, *co = NULL, *ct = NULL; 00916 int x; 00917 00918 /* Rebuild the compat table to recalculate the current target arch. */ 00919 00920 rpmSetMachine(NULL, NULL); 00921 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS); 00922 rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS); 00923 00924 if (target && *target) { 00925 char *c; 00926 /* Set arch and os from specified build target */ 00927 ca = xstrdup(*target); 00928 if ((c = strchr(ca, '-')) != NULL) { 00929 *c++ = '\0'; 00930 00931 if ((co = strrchr(c, '-')) == NULL) { 00932 co = c; 00933 } else { 00934 if (!xstrcasecmp(co, "-gnu")) 00935 *co = '\0'; 00936 if ((co = strrchr(c, '-')) == NULL) 00937 co = c; 00938 else 00939 co++; 00940 } 00941 if (co != NULL) co = xstrdup(co); 00942 } 00943 } else { 00944 const char *a = NULL; 00945 const char *o = NULL; 00946 /* Set build target from rpm arch and os */ 00947 getMachineInfo(ARCH, &a, NULL); 00948 ca = (a) ? xstrdup(a) : NULL; 00949 getMachineInfo(OS, &o, NULL); 00950 co = (o) ? xstrdup(o) : NULL; 00951 } 00952 00953 /* If still not set, Set target arch/os from default uname(2) values */ 00954 if (ca == NULL) { 00955 const char *a = NULL; 00956 defaultMachine(&a, NULL); 00957 ca = (a) ? xstrdup(a) : NULL; 00958 } 00959 if (ca != NULL) 00960 for (x = 0; ca[x] != '\0'; x++) 00961 ca[x] = (char)xtolower(ca[x]); 00962 00963 if (co == NULL) { 00964 const char *o = NULL; 00965 defaultMachine(NULL, &o); 00966 co = (o) ? xstrdup(o) : NULL; 00967 } 00968 if (co != NULL) 00969 for (x = 0; co[x] != '\0'; x++) 00970 co[x] = (char)xtolower(co[x]); 00971 00972 /* XXX For now, set canonical target to arch-os */ 00973 if (ct == NULL) { 00974 ct = xmalloc(strlen(ca) + sizeof("-") + strlen(co)); 00975 sprintf(ct, "%s-%s", ca, co); 00976 } 00977 00978 /* 00979 * XXX All this macro pokery/jiggery could be achieved by doing a delayed 00980 * rpmInitMacros(NULL, PER-PLATFORM-MACRO-FILE-NAMES); 00981 */ 00982 delMacro(NULL, "_target"); 00983 addMacro(NULL, "_target", NULL, ct, RMIL_RPMRC); 00984 delMacro(NULL, "_target_cpu"); 00985 addMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC); 00986 delMacro(NULL, "_target_os"); 00987 addMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC); 00988 00989 if (canontarget) 00990 *canontarget = ct; 00991 else 00992 ct = _free(ct); 00993 ca = _free(ca); 00994 /*@-usereleased@*/ 00995 co = _free(co); 00996 /*@=usereleased@*/ 00997 } 00998 00999 void rpmFreeRpmrc(void) 01000 /*@globals current, tables, defaultsInitialized @*/ 01001 /*@modifies current, tables, defaultsInitialized @*/ 01002 { 01003 int i, j, k; 01004 01005 (void)mireFreeAll(platpat, nplatpat); 01006 platpat = NULL; 01007 nplatpat = 0; 01008 01009 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) { 01010 tableType t; 01011 t = tables + i; 01012 if (t->equiv.list) { 01013 for (j = 0; j < t->equiv.count; j++) 01014 t->equiv.list[j].name = _free(t->equiv.list[j].name); 01015 t->equiv.list = _free(t->equiv.list); 01016 t->equiv.count = 0; 01017 } 01018 if (t->cache.cache) { 01019 for (j = 0; j < t->cache.size; j++) { 01020 machCacheEntry e; 01021 e = t->cache.cache + j; 01022 if (e == NULL) 01023 /*@innercontinue@*/ continue; 01024 e->name = _free(e->name); 01025 if (e->equivs) { 01026 for (k = 0; k < e->count; k++) 01027 e->equivs[k] = _free(e->equivs[k]); 01028 e->equivs = _free(e->equivs); 01029 } 01030 } 01031 t->cache.cache = _free(t->cache.cache); 01032 t->cache.size = 0; 01033 } 01034 if (t->defaults) { 01035 for (j = 0; j < t->defaultsLength; j++) { 01036 t->defaults[j].name = _free(t->defaults[j].name); 01037 t->defaults[j].defName = _free(t->defaults[j].defName); 01038 } 01039 t->defaults = _free(t->defaults); 01040 t->defaultsLength = 0; 01041 } 01042 if (t->canons) { 01043 for (j = 0; j < t->canonsLength; j++) { 01044 t->canons[j].name = _free(t->canons[j].name); 01045 t->canons[j].short_name = _free(t->canons[j].short_name); 01046 } 01047 t->canons = _free(t->canons); 01048 t->canonsLength = 0; 01049 } 01050 } 01051 01052 current[OS] = _free(current[OS]); 01053 current[ARCH] = _free(current[ARCH]); 01054 defaultsInitialized = 0; 01055 /*@-globstate -nullstate@*/ /* FIX: platpat/current may be NULL */ 01056 return; 01057 /*@=globstate =nullstate@*/ 01058 } 01059 01064 static int rpmReadRC(const char *macrofiles) 01065 /*@globals defaultsInitialized, 01066 rpmGlobalMacroContext, rpmCLIMacroContext, h_errno, 01067 fileSystem, internalState @*/ 01068 /*@modifies defaultsInitialized, rpmGlobalMacroContext, 01069 fileSystem, internalState @*/ 01070 { 01071 int rc = 0; 01072 01073 if (!defaultsInitialized) { 01074 setDefaults(); 01075 defaultsInitialized = 1; 01076 } 01077 01078 /* Read macro files. */ 01079 { const char *mfpath = rpmExpand(macrofiles, NULL); 01080 01081 if (mfpath != NULL) { 01082 rpmInitMacros(NULL, mfpath); 01083 mfpath = _free(mfpath); 01084 } 01085 } 01086 01087 return rc; 01088 } 01089 01090 int rpmReadConfigFiles(/*@unused@*/ const char * file, 01091 const char * target) 01092 /*@globals configTarget, rpmMacrofiles @*/ 01093 /*@modifies configTarget @*/ 01094 { 01095 mode_t mode = 0022; 01096 01097 #ifdef PREMACROFILES 01098 if (rpmReadRC(PREMACROFILES)) return -1; 01099 #endif 01100 01101 /* Reset umask to its default umask(2) value. */ 01102 mode = umask(mode); 01103 01104 configTarget = target; 01105 01106 /* Preset target macros */ 01107 /*@-nullstate@*/ /* FIX: target can be NULL */ 01108 rpmRebuildTargetVars(&target, NULL); 01109 01110 /* Read the files */ 01111 /*@-globs@*/ 01112 if (rpmReadRC(rpmMacrofiles)) return -1; 01113 /*@=globs@*/ 01114 01115 /* Reset target macros */ 01116 rpmRebuildTargetVars(&target, NULL); 01117 /*@=nullstate@*/ 01118 01119 /* Finally set target platform */ 01120 { const char *cpu = rpmExpand("%{_target_cpu}", NULL); 01121 const char *os = rpmExpand("%{_target_os}", NULL); 01122 rpmSetMachine(cpu, os); 01123 01124 cpu = _free(cpu); 01125 os = _free(os); 01126 } 01127 configTarget = NULL; 01128 01129 /* Force Lua state initialization */ 01130 #ifdef WITH_LUA 01131 (void)rpmluaGetPrintBuffer(NULL); 01132 #if defined(RPM_VENDOR_OPENPKG) /* rpm-lua-extensions-based-on-rpm-lib-functionality */ 01133 (void)rpmluaextActivate(rpmluaGetGlobalState()); 01134 #endif /* RPM_VENDOR_OPENPKG */ 01135 #endif 01136 01137 return 0; 01138 } 01139 01140 int rpmShowRC(FILE * fp) 01141 { 01142 rpmds ds = NULL; 01143 int i; 01144 machEquivTable equivTable; 01145 int xx; 01146 miRE mire; 01147 01148 /* the caller may set the build arch which should be printed here */ 01149 fprintf(fp, "ARCHITECTURE AND OS:\n"); 01150 fprintf(fp, "build arch : %s\n", current[ARCH]); 01151 01152 fprintf(fp, "compatible build archs:"); 01153 equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv; 01154 for (i = 0; i < equivTable->count; i++) 01155 fprintf(fp," %s", equivTable->list[i].name); 01156 fprintf(fp, "\n"); 01157 01158 fprintf(fp, "build os : %s\n", current[OS]); 01159 01160 fprintf(fp, "compatible build os's :"); 01161 equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv; 01162 for (i = 0; i < equivTable->count; i++) 01163 fprintf(fp," %s", equivTable->list[i].name); 01164 fprintf(fp, "\n"); 01165 01166 fprintf(fp, "install arch : %s\n", current[ARCH]); 01167 fprintf(fp, "install os : %s\n", current[OS]); 01168 01169 fprintf(fp, "compatible archs :"); 01170 for (mire = platpat, i = 0; i < nplatpat; i++) 01171 fprintf(fp, " %s", mire[i].pattern); 01172 fprintf(fp, "\n"); 01173 01174 fprintf(fp, "compatible os's :"); 01175 equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv; 01176 for (i = 0; i < equivTable->count; i++) 01177 fprintf(fp," %s", equivTable->list[i].name); 01178 fprintf(fp, "\n"); 01179 01180 { const char * s = rpmExpand("%{?optflags}", NULL); 01181 fprintf(fp, "%-21s : %s\n", "optflags", ((s && *s) ? s : "(not set)")); 01182 s = _free(s); 01183 01184 #ifdef WITH_LUA 01185 fprintf(fp, "\nLUA MODULES:\n"); 01186 /*@-globs@*/ 01187 s = rpmExpand(rpmluaFiles, NULL); 01188 /*@=globs@*/ 01189 fprintf(fp, "%-21s : %s\n", "luafiles", ((s && *s) ? s : "(not set)")); 01190 s = _free(s); 01191 /*@-globs@*/ 01192 s = rpmExpand(rpmluaPath, NULL); 01193 /*@=globs@*/ 01194 fprintf(fp, "%-21s : %s\n", "luapath", ((s && *s) ? s : "(not set)")); 01195 s = _free(s); 01196 #endif 01197 01198 fprintf(fp, "\nMACRO DEFINITIONS:\n"); 01199 /*@-globs@*/ 01200 s = rpmExpand(rpmMacrofiles, NULL); 01201 /*@=globs@*/ 01202 fprintf(fp, "%-21s : %s\n", "macrofiles", ((s && *s) ? s : "(not set)")); 01203 s = _free(s); 01204 } 01205 01206 if (rpmIsVerbose()) { 01207 rpmPRCO PRCO = rpmdsNewPRCO(NULL); 01208 xx = rpmdsSysinfo(PRCO, NULL); 01209 ds = rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME); 01210 if (ds != NULL) { 01211 const char * fn = (_sysinfo_path ? _sysinfo_path : "/etc/rpm/sysinfo"); 01212 fprintf(fp, _("Configured system provides (from %s):\n"), fn); 01213 ds = rpmdsInit(ds); 01214 while (rpmdsNext(ds) >= 0) { 01215 const char * DNEVR = rpmdsDNEVR(ds); 01216 if (DNEVR != NULL) 01217 fprintf(fp, " %s\n", DNEVR+2); 01218 } 01219 (void)rpmdsFree(ds); 01220 ds = NULL; 01221 fprintf(fp, "\n"); 01222 } 01223 PRCO = rpmdsFreePRCO(PRCO); 01224 } 01225 01226 if (rpmIsVerbose()) { 01227 fprintf(fp, _("Features provided by rpmlib installer:\n")); 01228 xx = rpmdsRpmlib(&ds, NULL); 01229 ds = rpmdsInit(ds); 01230 while (rpmdsNext(ds) >= 0) { 01231 const char * DNEVR = rpmdsDNEVR(ds); 01232 if (DNEVR != NULL) 01233 fprintf(fp, " %s\n", DNEVR+2); 01234 } 01235 (void)rpmdsFree(ds); 01236 ds = NULL; 01237 fprintf(fp, "\n"); 01238 01239 if(cpuinfoP == NULL) 01240 xx = rpmdsCpuinfo(&cpuinfoP, NULL); 01241 if (cpuinfoP != NULL) { 01242 #if defined(WITH_CPUINFO) 01243 const char * fn = "libcpuinfo"; 01244 #else 01245 const char * fn = (_cpuinfo_path ? _cpuinfo_path : "/proc/cpuinfo"); 01246 #endif 01247 fprintf(fp, 01248 _("Features provided by current cpuinfo (from %s):\n"), fn); 01249 /*@-mods@*/ 01250 cpuinfoP = rpmdsInit(cpuinfoP); 01251 while (rpmdsNext(cpuinfoP) >= 0) { 01252 const char * DNEVR = rpmdsDNEVR(cpuinfoP); 01253 if (DNEVR != NULL) 01254 fprintf(fp, " %s\n", DNEVR+2); 01255 } 01256 (void)rpmdsFree(cpuinfoP); 01257 cpuinfoP = NULL; 01258 /*@=mods@*/ 01259 01260 fprintf(fp, "\n"); 01261 } 01262 } 01263 01264 if (rpmIsDebug()) { 01265 xx = rpmdsGetconf(&ds, NULL); 01266 if (ds != NULL) { 01267 fprintf(fp, 01268 _("Features provided by current getconf:\n")); 01269 ds = rpmdsInit(ds); 01270 while (rpmdsNext(ds) >= 0) { 01271 const char * DNEVR = rpmdsDNEVR(ds); 01272 if (DNEVR != NULL) 01273 fprintf(fp, " %s\n", DNEVR+2); 01274 } 01275 (void)rpmdsFree(ds); 01276 ds = NULL; 01277 fprintf(fp, "\n"); 01278 } 01279 01280 xx = rpmdsUname(&ds, NULL); 01281 if (ds != NULL) { 01282 fprintf(fp, 01283 _("Features provided by current uname:\n")); 01284 ds = rpmdsInit(ds); 01285 while (rpmdsNext(ds) >= 0) { 01286 const char * DNEVR = rpmdsDNEVR(ds); 01287 if (DNEVR != NULL) 01288 fprintf(fp, " %s\n", DNEVR+2); 01289 } 01290 (void)rpmdsFree(ds); 01291 ds = NULL; 01292 fprintf(fp, "\n"); 01293 } 01294 } 01295 01296 rpmDumpMacroTable(NULL, fp); 01297 01298 return 0; 01299 }