rpm
4.5
|
00001 /*@-bounds@*/ 00002 #include "system.h" 00003 00004 #include <stdarg.h> 00005 #if defined(__linux__) && defined(__powerpc__) 00006 #include <setjmp.h> 00007 #endif 00008 00009 #if HAVE_SYS_SYSTEMCFG_H 00010 #include <sys/systemcfg.h> 00011 #else 00012 #define __power_pc() 0 00013 #endif 00014 00015 #include "rpmio_internal.h" 00016 #include <rpmcli.h> 00017 #include <rpmmacro.h> 00018 #include <rpmlua.h> 00019 #include <rpmds.h> 00020 00021 #define _MIRE_INTERNAL 00022 #include <mire.h> 00023 00024 #include "misc.h" 00025 #include "debug.h" 00026 00027 /*@observer@*/ /*@checked@*/ 00028 const char *rpmRcfiles = RPMRCFILES; 00029 00030 /*@unchecked@*/ /*@null@*/ 00031 static const char * configTarget = NULL; 00032 00033 /*@observer@*/ /*@unchecked@*/ 00034 static const char * platform = "/etc/rpm/platform"; 00035 /*@only@*/ /*@relnull@*/ /*@unchecked@*/ 00036 void * platpat = NULL; 00037 /*@unchecked@*/ 00038 int nplatpat = 0; 00039 00040 typedef /*@owned@*/ const char * cptr_t; 00041 00042 typedef struct machCacheEntry_s { 00043 const char * name; 00044 int count; 00045 cptr_t * equivs; 00046 int visited; 00047 } * machCacheEntry; 00048 00049 typedef struct machCache_s { 00050 machCacheEntry cache; 00051 int size; 00052 } * machCache; 00053 00054 typedef struct machEquivInfo_s { 00055 const char * name; 00056 int score; 00057 } * machEquivInfo; 00058 00059 typedef struct machEquivTable_s { 00060 int count; 00061 machEquivInfo list; 00062 } * machEquivTable; 00063 00064 struct rpmvarValue { 00065 const char * value; 00066 /* eventually, this arch will be replaced with a generic condition */ 00067 const char * arch; 00068 /*@only@*/ /*@null@*/ struct rpmvarValue * next; 00069 }; 00070 00071 struct rpmOption { 00072 const char * name; 00073 int var; 00074 int archSpecific; 00075 /*@unused@*/ int required; 00076 int macroize; 00077 int localize; 00078 /*@unused@*/ struct rpmOptionValue * value; 00079 }; 00080 00081 typedef struct defaultEntry_s { 00082 /*@owned@*/ /*@null@*/ const char * name; 00083 /*@owned@*/ /*@null@*/ const char * defName; 00084 } * defaultEntry; 00085 00086 typedef struct canonEntry_s { 00087 /*@owned@*/ const char * name; 00088 /*@owned@*/ const char * short_name; 00089 short num; 00090 } * canonEntry; 00091 00092 /* tags are 'key'canon, 'key'translate, 'key'compat 00093 * 00094 * for giggles, 'key'_canon, 'key'_compat, and 'key'_canon will also work 00095 */ 00096 typedef struct tableType_s { 00097 /*@observer@*/ const char * const key; 00098 const int hasCanon; 00099 const int hasTranslate; 00100 struct machEquivTable_s equiv; 00101 struct machCache_s cache; 00102 defaultEntry defaults; 00103 canonEntry canons; 00104 int defaultsLength; 00105 int canonsLength; 00106 } * tableType; 00107 00108 /*@-fullinitblock@*/ 00109 /*@unchecked@*/ 00110 static struct tableType_s tables[RPM_MACHTABLE_COUNT] = { 00111 { "arch", 1, 0 }, 00112 { "os", 1, 0 }, 00113 { "buildarch", 0, 1 }, 00114 { "buildos", 0, 1 } 00115 }; 00116 00117 /* this *must* be kept in alphabetical order */ 00118 /* The order of the flags is archSpecific, required, macroize, localize */ 00119 00120 #define RPMVAR_OPTFLAGS 3 00121 #define RPMVAR_INCLUDE 43 00122 #define RPMVAR_MACROFILES 49 00123 00124 #define RPMVAR_NUM 55 /* number of RPMVAR entries */ 00125 /*@unchecked@*/ 00126 static struct rpmOption optionTable[] = { 00127 { "include", RPMVAR_INCLUDE, 0, 1, 0, 2 }, 00128 { "macrofiles", RPMVAR_MACROFILES, 0, 0, 0, 1 }, 00129 { "optflags", RPMVAR_OPTFLAGS, 1, 0, 1, 0 }, 00130 }; 00131 /*@=fullinitblock@*/ 00132 00133 /*@unchecked@*/ 00134 static int optionTableSize = sizeof(optionTable) / sizeof(*optionTable); 00135 00136 #define OS 0 00137 #define ARCH 1 00138 00139 /*@unchecked@*/ 00140 static cptr_t current[2]; 00141 00142 /*@unchecked@*/ 00143 static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH }; 00144 00145 /*@unchecked@*/ 00146 static struct rpmvarValue values[RPMVAR_NUM]; 00147 00148 /*@unchecked@*/ 00149 static int defaultsInitialized = 0; 00150 00151 /* prototypes */ 00152 static void rpmRebuildTargetVars(/*@null@*/ const char **target, /*@null@*/ const char ** canontarget) 00153 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00154 /*@modifies *canontarget, rpmGlobalMacroContext, 00155 fileSystem, internalState @*/; 00156 00157 static int optionCompare(const void * a, const void * b) 00158 /*@*/ 00159 { 00160 return xstrcasecmp(((struct rpmOption *) a)->name, 00161 ((struct rpmOption *) b)->name); 00162 } 00163 00164 static /*@observer@*/ /*@null@*/ machCacheEntry 00165 machCacheFindEntry(const machCache cache, const char * key) 00166 /*@*/ 00167 { 00168 int i; 00169 00170 for (i = 0; i < cache->size; i++) 00171 if (!strcmp(cache->cache[i].name, key)) return cache->cache + i; 00172 00173 return NULL; 00174 } 00175 00176 static int machCompatCacheAdd(char * name, const char * fn, int linenum, 00177 machCache cache) 00178 /*@globals internalState @*/ 00179 /*@modifies *name, cache->cache, cache->size, internalState @*/ 00180 { 00181 machCacheEntry entry = NULL; 00182 char * chptr; 00183 char * equivs; 00184 int delEntry = 0; 00185 int i; 00186 00187 while (*name && xisspace(*name)) name++; 00188 00189 chptr = name; 00190 while (*chptr && *chptr != ':') chptr++; 00191 if (!*chptr) { 00192 rpmError(RPMERR_RPMRC, _("missing second ':' at %s:%d\n"), fn, linenum); 00193 return 1; 00194 } else if (chptr == name) { 00195 rpmError(RPMERR_RPMRC, _("missing architecture name at %s:%d\n"), fn, 00196 linenum); 00197 return 1; 00198 } 00199 00200 while (*chptr == ':' || xisspace(*chptr)) chptr--; 00201 *(++chptr) = '\0'; 00202 equivs = chptr + 1; 00203 while (*equivs && xisspace(*equivs)) equivs++; 00204 if (!*equivs) { 00205 delEntry = 1; 00206 } 00207 00208 if (cache->size) { 00209 entry = machCacheFindEntry(cache, name); 00210 if (entry) { 00211 for (i = 0; i < entry->count; i++) 00212 entry->equivs[i] = _free(entry->equivs[i]); 00213 entry->equivs = _free(entry->equivs); 00214 entry->count = 0; 00215 } 00216 } 00217 00218 if (!entry) { 00219 cache->cache = xrealloc(cache->cache, 00220 (cache->size + 1) * sizeof(*cache->cache)); 00221 entry = cache->cache + cache->size++; 00222 entry->name = xstrdup(name); 00223 entry->count = 0; 00224 entry->visited = 0; 00225 } 00226 00227 if (delEntry) return 0; 00228 00229 while ((chptr = strtok(equivs, " ")) != NULL) { 00230 equivs = NULL; 00231 if (chptr[0] == '\0') /* does strtok() return "" ever?? */ 00232 continue; 00233 if (entry->count) 00234 entry->equivs = xrealloc(entry->equivs, sizeof(*entry->equivs) 00235 * (entry->count + 1)); 00236 else 00237 entry->equivs = xmalloc(sizeof(*entry->equivs)); 00238 00239 entry->equivs[entry->count] = xstrdup(chptr); 00240 entry->count++; 00241 } 00242 00243 return 0; 00244 } 00245 00246 static /*@observer@*/ /*@null@*/ machEquivInfo 00247 machEquivSearch(const machEquivTable table, const char * name) 00248 /*@*/ 00249 { 00250 int i; 00251 00252 for (i = 0; i < table->count; i++) 00253 if (!xstrcasecmp(table->list[i].name, name)) 00254 return table->list + i; 00255 00256 return NULL; 00257 } 00258 00259 static void machAddEquiv(machEquivTable table, const char * name, 00260 int distance) 00261 /*@modifies table->list, table->count @*/ 00262 { 00263 machEquivInfo equiv; 00264 00265 { int i; 00266 equiv = NULL; 00267 for (i = 0; i < table->count; i++) { 00268 if (xstrcasecmp(table->list[i].name, name)) 00269 continue; 00270 equiv = table->list + i; 00271 break; 00272 } 00273 } 00274 00275 if (!equiv) { 00276 if (table->count) 00277 table->list = xrealloc(table->list, (table->count + 1) 00278 * sizeof(*table->list)); 00279 else 00280 table->list = xmalloc(sizeof(*table->list)); 00281 00282 table->list[table->count].name = xstrdup(name); 00283 table->list[table->count++].score = distance; 00284 } 00285 } 00286 00287 static void machCacheEntryVisit(machCache cache, 00288 machEquivTable table, const char * name, int distance) 00289 /*@modifies table->list, table->count @*/ 00290 { 00291 machCacheEntry entry; 00292 int i; 00293 00294 entry = machCacheFindEntry(cache, name); 00295 if (!entry || entry->visited) return; 00296 00297 entry->visited = 1; 00298 00299 for (i = 0; i < entry->count; i++) { 00300 machAddEquiv(table, entry->equivs[i], distance); 00301 } 00302 00303 for (i = 0; i < entry->count; i++) { 00304 machCacheEntryVisit(cache, table, entry->equivs[i], distance + 1); 00305 } 00306 } 00307 00308 static void rebuildCompatTables(int type, const char * name) 00309 /*@globals tables, internalState @*/ 00310 /*@modifies tables, internalState @*/ 00311 { 00312 machCache cache = &tables[currTables[type]].cache; 00313 machEquivTable table = &tables[currTables[type]].equiv; 00314 const char * key = name; 00315 int i; 00316 00317 for (i = 0; i < cache->size; i++) 00318 cache->cache[i].visited = 0; 00319 00320 while (table->count > 0) { 00321 --table->count; 00322 table->list[table->count].name = _free(table->list[table->count].name); 00323 } 00324 table->count = 0; 00325 table->list = _free(table->list); 00326 00327 /* 00328 * We have a general graph built using strings instead of pointers. 00329 * Yuck. We have to start at a point at traverse it, remembering how 00330 * far away everything is. 00331 */ 00332 /*@-nullstate@*/ /* FIX: table->list may be NULL. */ 00333 machAddEquiv(table, key, 1); 00334 machCacheEntryVisit(cache, table, key, 2); 00335 return; 00336 /*@=nullstate@*/ 00337 } 00338 00339 static int addCanon(canonEntry * table, int * tableLen, char * line, 00340 const char * fn, int lineNum) 00341 /*@globals internalState @*/ 00342 /*@modifies *table, *tableLen, *line, internalState @*/ 00343 { 00344 canonEntry t; 00345 char *s, *s1; 00346 const char * tname; 00347 const char * tshort_name; 00348 int tnum; 00349 00350 (*tableLen) += 2; 00351 /*@-unqualifiedtrans@*/ 00352 *table = xrealloc(*table, sizeof(**table) * (*tableLen)); 00353 /*@=unqualifiedtrans@*/ 00354 00355 t = & ((*table)[*tableLen - 2]); 00356 00357 tname = strtok(line, ": \t"); 00358 tshort_name = strtok(NULL, " \t"); 00359 s = strtok(NULL, " \t"); 00360 if (! (tname && tshort_name && s)) { 00361 rpmError(RPMERR_RPMRC, _("Incomplete data line at %s:%d\n"), 00362 fn, lineNum); 00363 return RPMERR_RPMRC; 00364 } 00365 if (strtok(NULL, " \t")) { 00366 rpmError(RPMERR_RPMRC, _("Too many args in data line at %s:%d\n"), 00367 fn, lineNum); 00368 return RPMERR_RPMRC; 00369 } 00370 00371 /*@-nullpass@*/ /* LCL: s != NULL here. */ 00372 tnum = strtoul(s, &s1, 10); 00373 if ((*s1) || (s1 == s) || (tnum == ULONG_MAX)) { 00374 rpmError(RPMERR_RPMRC, _("Bad arch/os number: %s (%s:%d)\n"), s, 00375 fn, lineNum); 00376 return(RPMERR_RPMRC); 00377 } 00378 /*@=nullpass@*/ 00379 00380 t[0].name = xstrdup(tname); 00381 t[0].short_name = (tshort_name ? xstrdup(tshort_name) : xstrdup("")); 00382 t[0].num = tnum; 00383 00384 /* From A B C entry */ 00385 /* Add B B C entry */ 00386 t[1].name = (tshort_name ? xstrdup(tshort_name) : xstrdup("")); 00387 t[1].short_name = (tshort_name ? xstrdup(tshort_name) : xstrdup("")); 00388 t[1].num = tnum; 00389 00390 return 0; 00391 } 00392 00393 static int addDefault(defaultEntry * table, int * tableLen, char * line, 00394 const char * fn, int lineNum) 00395 /*@globals internalState @*/ 00396 /*@modifies *table, *tableLen, *line, internalState @*/ 00397 { 00398 defaultEntry t; 00399 00400 (*tableLen)++; 00401 /*@-unqualifiedtrans@*/ 00402 *table = xrealloc(*table, sizeof(**table) * (*tableLen)); 00403 /*@=unqualifiedtrans@*/ 00404 00405 t = & ((*table)[*tableLen - 1]); 00406 00407 /*@-temptrans@*/ 00408 t->name = strtok(line, ": \t"); 00409 t->defName = strtok(NULL, " \t"); 00410 if (! (t->name && t->defName)) { 00411 rpmError(RPMERR_RPMRC, _("Incomplete default line at %s:%d\n"), 00412 fn, lineNum); 00413 return RPMERR_RPMRC; 00414 } 00415 if (strtok(NULL, " \t")) { 00416 rpmError(RPMERR_RPMRC, _("Too many args in default line at %s:%d\n"), 00417 fn, lineNum); 00418 return RPMERR_RPMRC; 00419 } 00420 00421 t->name = xstrdup(t->name); 00422 t->defName = (t->defName ? xstrdup(t->defName) : NULL); 00423 /*@=temptrans@*/ 00424 00425 return 0; 00426 } 00427 00428 static /*@null@*/ canonEntry lookupInCanonTable(const char * name, 00429 const canonEntry table, int tableLen) 00430 /*@*/ 00431 { 00432 while (tableLen) { 00433 tableLen--; 00434 if (strcmp(name, table[tableLen].name)) 00435 continue; 00436 /*@-immediatetrans -retalias@*/ 00437 return &(table[tableLen]); 00438 /*@=immediatetrans =retalias@*/ 00439 } 00440 00441 return NULL; 00442 } 00443 00444 static /*@observer@*/ /*@null@*/ 00445 const char * lookupInDefaultTable(const char * name, 00446 const defaultEntry table, int tableLen) 00447 /*@*/ 00448 { 00449 while (tableLen) { 00450 tableLen--; 00451 if (table[tableLen].name && !strcmp(name, table[tableLen].name)) 00452 return table[tableLen].defName; 00453 } 00454 00455 return name; 00456 } 00457 00458 static /*@observer@*/ /*@null@*/ 00459 const char * rpmGetVarArch(int var, /*@null@*/ const char * arch) 00460 /*@*/ 00461 { 00462 const struct rpmvarValue * next; 00463 00464 if (arch == NULL) arch = current[ARCH]; 00465 00466 if (arch) { 00467 next = &values[var]; 00468 while (next) { 00469 if (next->arch && !strcmp(next->arch, arch)) return next->value; 00470 next = next->next; 00471 } 00472 } 00473 00474 next = values + var; 00475 while (next && next->arch) next = next->next; 00476 00477 return next ? next->value : NULL; 00478 } 00479 00480 /* this doesn't free the passed pointer! */ 00481 static void freeRpmVar(/*@only@*/ struct rpmvarValue * orig) 00482 /*@modifies *orig @*/ 00483 { 00484 struct rpmvarValue * next, * var = orig; 00485 00486 while (var) { 00487 next = var->next; 00488 var->arch = _free(var->arch); 00489 var->value = _free(var->value); 00490 00491 /*@-branchstate@*/ 00492 if (var != orig) var = _free(var); 00493 /*@=branchstate@*/ 00494 var = next; 00495 } 00496 } 00497 00502 static void rpmSetVar(int var, const char * val) 00503 /*@globals values @*/ 00504 /*@modifies values @*/ 00505 { 00506 /*@-immediatetrans@*/ 00507 freeRpmVar(&values[var]); 00508 /*@=immediatetrans@*/ 00509 values[var].value = (val ? xstrdup(val) : NULL); 00510 } 00511 00512 static void setVarDefault(int var, const char * macroname, const char * val, 00513 /*@null@*/ const char * body) 00514 /*@globals rpmGlobalMacroContext, internalState @*/ 00515 /*@modifies rpmGlobalMacroContext, internalState @*/ 00516 { 00517 if (var >= 0) { /* XXX Dying ... */ 00518 if (rpmGetVarArch(var, NULL)) return; 00519 rpmSetVar(var, val); 00520 } 00521 if (body == NULL) 00522 body = val; 00523 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT); 00524 } 00525 00526 static void setPathDefault(int var, const char * macroname, const char * subdir) 00527 /*@globals rpmGlobalMacroContext, h_errno, internalState @*/ 00528 /*@modifies rpmGlobalMacroContext, internalState @*/ 00529 { 00530 00531 if (var >= 0) { /* XXX Dying ... */ 00532 const char * topdir; 00533 char * fn; 00534 00535 if (rpmGetVarArch(var, NULL)) return; 00536 00537 topdir = rpmGetPath("%{_topdir}", NULL); 00538 00539 fn = alloca(strlen(topdir) + strlen(subdir) + 2); 00540 strcpy(fn, topdir); 00541 if (fn[strlen(topdir) - 1] != '/') 00542 strcat(fn, "/"); 00543 strcat(fn, subdir); 00544 00545 rpmSetVar(var, fn); 00546 topdir = _free(topdir); 00547 } 00548 00549 if (macroname != NULL) { 00550 #define _TOPDIRMACRO "%{_topdir}/" 00551 char *body = alloca(sizeof(_TOPDIRMACRO) + strlen(subdir)); 00552 strcpy(body, _TOPDIRMACRO); 00553 strcat(body, subdir); 00554 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT); 00555 #undef _TOPDIRMACRO 00556 } 00557 } 00558 00559 /*@observer@*/ /*@unchecked@*/ 00560 static const char * ___build_pre = "\n\ 00561 RPM_SOURCE_DIR=\"%{_sourcedir}\"\n\ 00562 RPM_BUILD_DIR=\"%{_builddir}\"\n\ 00563 RPM_OPT_FLAGS=\"%{optflags}\"\n\ 00564 RPM_ARCH=\"%{_arch}\"\n\ 00565 RPM_OS=\"%{_os}\"\n\ 00566 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\n\ 00567 RPM_DOC_DIR=\"%{_docdir}\"\n\ 00568 export RPM_DOC_DIR\n\ 00569 RPM_PACKAGE_NAME=\"%{name}\"\n\ 00570 RPM_PACKAGE_VERSION=\"%{version}\"\n\ 00571 RPM_PACKAGE_RELEASE=\"%{release}\"\n\ 00572 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\n\ 00573 %{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\n\ 00574 export RPM_BUILD_ROOT\n}\ 00575 "; 00576 00577 static void setDefaults(void) 00578 /*@globals rpmGlobalMacroContext, h_errno, internalState @*/ 00579 /*@modifies rpmGlobalMacroContext, internalState @*/ 00580 { 00581 00582 addMacro(NULL, "_usr", NULL, "/usr", RMIL_DEFAULT); 00583 addMacro(NULL, "_var", NULL, "/var", RMIL_DEFAULT); 00584 addMacro(NULL, "_prefix", NULL, "%{_usr}", RMIL_DEFAULT); 00585 00586 addMacro(NULL, "___build_pre", NULL, ___build_pre, RMIL_DEFAULT); 00587 00588 setVarDefault(-1, "_topdir", 00589 "/usr/src/rpm", "%{_usr}/src/rpm"); 00590 setVarDefault(-1, "_tmppath", 00591 "/var/tmp", "%{_var}/tmp"); 00592 setVarDefault(-1, "_dbpath", 00593 "/var/lib/rpm", "%{_var}/lib/rpm"); 00594 setVarDefault(-1, "_defaultdocdir", 00595 "/usr/share/doc", "%{_usr}/share/doc"); 00596 00597 setVarDefault(-1, "_rpmfilename", 00598 "%%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm",NULL); 00599 00600 setVarDefault(RPMVAR_OPTFLAGS, "optflags", 00601 "-O2 -g", NULL); 00602 setVarDefault(-1, "sigtype", 00603 "none", NULL); 00604 setVarDefault(-1, "_buildshell", 00605 "/bin/sh", NULL); 00606 00607 setPathDefault(-1, "_builddir", "BUILD"); 00608 setPathDefault(-1, "_rpmdir", "RPMS"); 00609 setPathDefault(-1, "_srcrpmdir", "SRPMS"); 00610 setPathDefault(-1, "_sourcedir", "SOURCES"); 00611 setPathDefault(-1, "_specdir", "SPECS"); 00612 00613 } 00614 00615 static void rpmSetVarArch(int var, const char * val, 00616 /*@null@*/ const char * arch) 00617 /*@globals values, internalState @*/ 00618 /*@modifies values, internalState @*/ 00619 { 00620 struct rpmvarValue * next = values + var; 00621 00622 if (next->value) { 00623 if (arch) { 00624 while (next->next) { 00625 if (next->arch && !strcmp(next->arch, arch)) break; 00626 next = next->next; 00627 } 00628 } else { 00629 while (next->next) { 00630 if (!next->arch) break; 00631 next = next->next; 00632 } 00633 } 00634 00635 /*@-nullpass@*/ /* LCL: arch != NULL here. */ 00636 if (next->arch && arch && !strcmp(next->arch, arch)) { 00637 /*@=nullpass@*/ 00638 next->value = _free(next->value); 00639 next->arch = _free(next->arch); 00640 } else if (next->arch || arch) { 00641 next->next = xmalloc(sizeof(*next->next)); 00642 next = next->next; 00643 next->value = NULL; 00644 next->arch = NULL; 00645 next->next = NULL; 00646 } 00647 } 00648 00649 next->value = _free(next->value); 00650 next->value = xstrdup(val); 00651 next->arch = (arch ? xstrdup(arch) : NULL); 00652 } 00653 00654 /*@-usedef@*/ /*@ FIX: se usage inconsistent, W2DO? */ 00655 static int doReadRC( /*@killref@*/ FD_t fd, const char * urlfn) 00656 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00657 /*@modifies fd, rpmGlobalMacroContext, fileSystem, internalState @*/ 00658 { 00659 const char *s; 00660 char *se, *next; 00661 int linenum = 0; 00662 struct rpmOption searchOption, * option; 00663 int rc; 00664 00665 /* XXX really need rc = Slurp(fd, const char * filename, char ** buf) */ 00666 { off_t size = fdSize(fd); 00667 size_t nb = (size >= 0 ? size : (8*BUFSIZ - 2)); 00668 if (nb == 0) { 00669 (void) Fclose(fd); 00670 return 0; 00671 } 00672 next = alloca(nb + 2); 00673 next[0] = '\0'; 00674 rc = Fread(next, sizeof(*next), nb, fd); 00675 if (Ferror(fd) || (size > 0 && rc != nb)) { /* XXX Feof(fd) */ 00676 rpmError(RPMERR_RPMRC, _("Failed to read %s: %s.\n"), urlfn, 00677 Fstrerror(fd)); 00678 rc = 1; 00679 } else 00680 rc = 0; 00681 (void) Fclose(fd); 00682 if (rc) return rc; 00683 next[nb] = '\n'; 00684 next[nb + 1] = '\0'; 00685 } 00686 00687 /*@-branchstate@*/ 00688 while (*next != '\0') { 00689 linenum++; 00690 00691 s = se = next; 00692 00693 /* Find end-of-line. */ 00694 while (*se && *se != '\n') se++; 00695 if (*se != '\0') *se++ = '\0'; 00696 next = se; 00697 00698 /* Trim leading spaces */ 00699 while (*s && xisspace(*s)) s++; 00700 00701 /* We used to allow comments to begin anywhere, but not anymore. */ 00702 if (*s == '#' || *s == '\0') continue; 00703 00704 /* Find end-of-keyword. */ 00705 se = (char *)s; 00706 while (*se && !xisspace(*se) && *se != ':') se++; 00707 00708 if (xisspace(*se)) { 00709 *se++ = '\0'; 00710 while (*se && xisspace(*se) && *se != ':') se++; 00711 } 00712 00713 if (*se != ':') { 00714 rpmError(RPMERR_RPMRC, _("missing ':' (found 0x%02x) at %s:%d\n"), 00715 (unsigned)(0xff & *se), urlfn, linenum); 00716 return 1; 00717 } 00718 *se++ = '\0'; /* terminate keyword or option, point to value */ 00719 while (*se && xisspace(*se)) se++; 00720 00721 /* Find keyword in table */ 00722 searchOption.name = s; 00723 option = bsearch(&searchOption, optionTable, optionTableSize, 00724 sizeof(optionTable[0]), optionCompare); 00725 00726 if (option) { /* For configuration variables ... */ 00727 const char *arch, *val, *fn; 00728 00729 arch = val = fn = NULL; 00730 if (*se == '\0') { 00731 rpmError(RPMERR_RPMRC, _("missing argument for %s at %s:%d\n"), 00732 option->name, urlfn, linenum); 00733 return 1; 00734 } 00735 00736 switch (option->var) { 00737 case RPMVAR_INCLUDE: 00738 { FD_t fdinc; 00739 00740 s = se; 00741 while (*se && !xisspace(*se)) se++; 00742 if (*se != '\0') *se++ = '\0'; 00743 00744 rpmRebuildTargetVars(NULL, NULL); 00745 00746 fn = rpmGetPath(s, NULL); 00747 if (fn == NULL || *fn == '\0') { 00748 rpmError(RPMERR_RPMRC, _("%s expansion failed at %s:%d \"%s\"\n"), 00749 option->name, urlfn, linenum, s); 00750 fn = _free(fn); 00751 return 1; 00752 /*@notreached@*/ 00753 } 00754 00755 fdinc = Fopen(fn, "r.fpio"); 00756 if (fdinc == NULL || Ferror(fdinc)) { 00757 rpmError(RPMERR_RPMRC, _("cannot open %s at %s:%d: %s\n"), 00758 fn, urlfn, linenum, Fstrerror(fdinc)); 00759 rc = 1; 00760 } else { 00761 rc = doReadRC(fdinc, fn); 00762 } 00763 fn = _free(fn); 00764 if (rc) return rc; 00765 continue; /* XXX don't save include value as var/macro */ 00766 } /*@notreached@*/ /*@switchbreak@*/ break; 00767 case RPMVAR_MACROFILES: 00768 fn = rpmGetPath(se, NULL); 00769 if (fn == NULL || *fn == '\0') { 00770 rpmError(RPMERR_RPMRC, _("%s expansion failed at %s:%d \"%s\"\n"), 00771 option->name, urlfn, linenum, fn); 00772 fn = _free(fn); 00773 return 1; 00774 } 00775 se = (char *)fn; 00776 /*@switchbreak@*/ break; 00777 default: 00778 /*@switchbreak@*/ break; 00779 } 00780 00781 if (option->archSpecific) { 00782 arch = se; 00783 while (*se && !xisspace(*se)) se++; 00784 if (*se == '\0') { 00785 rpmError(RPMERR_RPMRC, 00786 _("missing architecture for %s at %s:%d\n"), 00787 option->name, urlfn, linenum); 00788 return 1; 00789 } 00790 *se++ = '\0'; 00791 while (*se && xisspace(*se)) se++; 00792 if (*se == '\0') { 00793 rpmError(RPMERR_RPMRC, 00794 _("missing argument for %s at %s:%d\n"), 00795 option->name, urlfn, linenum); 00796 return 1; 00797 } 00798 } 00799 00800 val = se; 00801 00802 /* Only add macros if appropriate for this arch */ 00803 if (option->macroize && 00804 (arch == NULL || !strcmp(arch, current[ARCH]))) { 00805 char *n, *name; 00806 n = name = xmalloc(strlen(option->name)+2); 00807 if (option->localize) 00808 *n++ = '_'; 00809 strcpy(n, option->name); 00810 addMacro(NULL, name, NULL, val, RMIL_RPMRC); 00811 free(name); 00812 } 00813 rpmSetVarArch(option->var, val, arch); 00814 fn = _free(fn); 00815 00816 } else { /* For arch/os compatibilty tables ... */ 00817 int gotit; 00818 int i; 00819 00820 gotit = 0; 00821 00822 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) { 00823 if (!strncmp(tables[i].key, s, strlen(tables[i].key))) 00824 /*@innerbreak@*/ break; 00825 } 00826 00827 if (i < RPM_MACHTABLE_COUNT) { 00828 const char *rest = s + strlen(tables[i].key); 00829 if (*rest == '_') rest++; 00830 00831 if (!strcmp(rest, "compat")) { 00832 if (machCompatCacheAdd(se, urlfn, linenum, 00833 &tables[i].cache)) 00834 return 1; 00835 gotit = 1; 00836 } else if (tables[i].hasTranslate && 00837 !strcmp(rest, "translate")) { 00838 if (addDefault(&tables[i].defaults, 00839 &tables[i].defaultsLength, 00840 se, urlfn, linenum)) 00841 return 1; 00842 gotit = 1; 00843 } else if (tables[i].hasCanon && 00844 !strcmp(rest, "canon")) { 00845 if (addCanon(&tables[i].canons, &tables[i].canonsLength, 00846 se, urlfn, linenum)) 00847 return 1; 00848 gotit = 1; 00849 } 00850 } 00851 00852 if (!gotit) { 00853 rpmError(RPMERR_RPMRC, _("bad option '%s' at %s:%d\n"), 00854 s, urlfn, linenum); 00855 } 00856 } 00857 } 00858 /*@=branchstate@*/ 00859 00860 return 0; 00861 } 00862 /*@=usedef@*/ 00863 00864 typedef struct cpu_vendor_os_gnu { 00865 /*@owned@*/ 00866 const char * str; 00867 /*@observer@*/ 00868 const char * cpu; 00869 /*@observer@*/ 00870 const char * vendor; 00871 /*@observer@*/ 00872 const char * os; 00873 /*@observer@*/ 00874 const char * gnu; 00875 } * CVOG_t; 00876 00879 /*@-bounds@*/ 00880 static int parseCVOG(const char * str, CVOG_t *cvogp) 00881 /*@modifies *cvogp @*/ 00882 { 00883 CVOG_t cvog = xcalloc(1, sizeof(*cvog)); 00884 char * p, * pe; 00885 00886 cvog->str = p = xstrdup(str); 00887 pe = p + strlen(p); 00888 while (pe-- > p && isspace(*pe)) 00889 *pe = '\0'; 00890 00891 cvog->cpu = p; 00892 cvog->vendor = "unknown"; 00893 cvog->os = "unknown"; 00894 cvog->gnu = ""; 00895 while (*p && !(*p == '-' || isspace(*p))) 00896 p++; 00897 if (*p != '\0') *p++ = '\0'; 00898 00899 cvog->vendor = p; 00900 while (*p && !(*p == '-' || isspace(*p))) 00901 p++; 00902 /*@-branchstate@*/ 00903 if (*p != '-') { 00904 if (*p != '\0') *p++ = '\0'; 00905 cvog->os = cvog->vendor; 00906 cvog->vendor = "unknown"; 00907 } else { 00908 if (*p != '\0') *p++ = '\0'; 00909 00910 cvog->os = p; 00911 while (*p && !(*p == '-' || isspace(*p))) 00912 p++; 00913 if (*p == '-') { 00914 *p++ = '\0'; 00915 00916 cvog->gnu = p; 00917 while (*p && !(*p == '-' || isspace(*p))) 00918 p++; 00919 } 00920 if (*p != '\0') *p++ = '\0'; 00921 } 00922 00923 if (cvogp) 00924 *cvogp = cvog; 00925 else { 00926 cvog->str = _free(cvog->str); 00927 cvog = _free(cvog); 00928 } 00929 /*@=branchstate@*/ 00930 return 0; 00931 } 00932 /*@=bounds@*/ 00933 00940 /*@null@*/ 00941 static void * mireFreeAll(/*@only@*/ /*@null@*/ miRE mire, int nre) 00942 /*@modifies mire@*/ 00943 { 00944 if (mire != NULL) { 00945 int i; 00946 for (i = 0; i < nre; i++) 00947 (void) mireClean(mire + i); 00948 mire = _free(mire); 00949 } 00950 return NULL; 00951 } 00952 00961 /*@null@*/ 00962 int mireAppend(rpmMireMode mode, int tag, const char * pattern, 00963 miRE * mi_rep, int * mi_nrep) 00964 /*@modifies *mi_rep, *mi_nrep @*/ 00965 { 00966 miRE mire; 00967 00968 mire = (*mi_rep); 00969 mire = xrealloc(mire, ((*mi_nrep) + 1) * sizeof(*mire)); 00970 (*mi_rep) = mire; 00971 mire += (*mi_nrep); 00972 (*mi_nrep)++; 00973 memset(mire, 0, sizeof(*mire)); 00974 mire->mode = mode; 00975 mire->tag = tag; 00976 return mireRegcomp(mire, pattern); 00977 } 00978 00984 /*@-bounds@*/ 00985 static int rpmPlatform(const char * platform) 00986 /*@globals nplatpat, platpat, 00987 rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00988 /*@modifies nplatpat, platpat, 00989 rpmGlobalMacroContext, fileSystem, internalState @*/ 00990 { 00991 CVOG_t cvog = NULL; 00992 char * b = NULL; 00993 ssize_t blen = 0; 00994 int init_platform = 0; 00995 miRE mi_re = NULL; 00996 int mi_nre = 0; 00997 char * p, * pe; 00998 int rc; 00999 int xx; 01000 01001 rc = rpmioSlurp(platform, &b, &blen); 01002 01003 if (rc || b == NULL || blen <= 0) { 01004 rc = -1; 01005 goto exit; 01006 } 01007 01008 p = b; 01009 for (pe = p; p && *p; p = pe) { 01010 pe = strchr(p, '\n'); 01011 if (pe) 01012 *pe++ = '\0'; 01013 01014 while (*p && xisspace(*p)) 01015 p++; 01016 if (*p == '\0' || *p == '#') 01017 continue; 01018 01019 if (init_platform) { 01020 char * t = p + strlen(p); 01021 while (--t > p && xisspace(*t)) 01022 *t = '\0'; 01023 if (t > p) 01024 xx = mireAppend(RPMMIRE_REGEX, 0, p, &mi_re, &mi_nre); 01025 continue; 01026 } 01027 01028 if (!parseCVOG(p, &cvog) && cvog != NULL) { 01029 addMacro(NULL, "_host_cpu", NULL, cvog->cpu, -1); 01030 addMacro(NULL, "_host_vendor", NULL, cvog->vendor, -1); 01031 addMacro(NULL, "_host_os", NULL, cvog->os, -1); 01032 } 01033 01034 p = rpmExpand("%{_host_cpu}-%{_host_vendor}-%{_host_os}", 01035 (cvog && *cvog->gnu ? "-" : NULL), 01036 (cvog ? cvog->gnu : NULL), NULL); 01037 xx = mireAppend(RPMMIRE_STRCMP, 0, p, &mi_re, &mi_nre); 01038 p = _free(p); 01039 01040 init_platform++; 01041 } 01042 rc = (init_platform ? 0 : -1); 01043 01044 exit: 01045 if (cvog) { 01046 cvog->str = _free(cvog->str); 01047 cvog = _free(cvog); 01048 } 01049 /*@-modobserver@*/ 01050 b = _free(b); 01051 /*@=modobserver@*/ 01052 if (rc == 0) { 01053 platpat = mireFreeAll(platpat, nplatpat); 01054 platpat = mi_re; 01055 nplatpat = mi_nre; 01056 } 01057 return rc; 01058 } 01059 /*@=bounds@*/ 01060 01061 int rpmPlatformScore(const char * platform, void * mi_re, int mi_nre) 01062 { 01063 miRE mire; 01064 int i; 01065 01066 if (mi_re == NULL) { 01067 mi_re = platpat; 01068 mi_nre = nplatpat; 01069 } 01070 01071 if ((mire = mi_re) != NULL) 01072 for (i = 0; i < mi_nre; i++) { 01073 if (!mireRegexec(mire + i, platform)) 01074 return (i + 1); 01075 } 01076 return 0; 01077 } 01078 01079 # if defined(__linux__) && defined(__i386__) 01080 #include <setjmp.h> 01081 #include <signal.h> 01082 01083 /* 01084 * Generic CPUID function 01085 */ 01086 static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) 01087 /*@modifies *eax, *ebx, *ecx, *edx @*/ 01088 { 01089 #ifdef __LCLINT__ 01090 *eax = *ebx = *ecx = *edx = 0; 01091 #endif 01092 asm volatile ( 01093 "pushl %%ebx \n" 01094 "cpuid \n" 01095 "movl %%ebx, %%esi \n" 01096 "popl %%ebx \n" 01097 : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) 01098 : "a" (op)); 01099 } 01100 01101 /* 01102 * CPUID functions returning a single datum 01103 */ 01104 static inline unsigned int cpuid_eax(unsigned int op) 01105 /*@*/ 01106 { 01107 unsigned int tmp, val; 01108 cpuid(op, &val, &tmp, &tmp, &tmp); 01109 return val; 01110 } 01111 01112 static inline unsigned int cpuid_ebx(unsigned int op) 01113 /*@*/ 01114 { 01115 unsigned int tmp, val; 01116 cpuid(op, &tmp, &val, &tmp, &tmp); 01117 return val; 01118 } 01119 01120 static inline unsigned int cpuid_ecx(unsigned int op) 01121 /*@*/ 01122 { 01123 unsigned int tmp, val; 01124 cpuid(op, &tmp, &tmp, &val, &tmp); 01125 return val; 01126 } 01127 01128 static inline unsigned int cpuid_edx(unsigned int op) 01129 /*@*/ 01130 { 01131 unsigned int tmp, val; 01132 cpuid(op, &tmp, &tmp, &tmp, &val); 01133 return val; 01134 } 01135 01136 /*@unchecked@*/ 01137 static sigjmp_buf jenv; 01138 01139 static inline void model3(int _unused) 01140 /*@globals internalState @*/ 01141 /*@modifies internalState @*/ 01142 { 01143 siglongjmp(jenv, 1); 01144 } 01145 01146 static inline int RPMClass(void) 01147 /*@globals internalState @*/ 01148 /*@modifies internalState @*/ 01149 { 01150 int cpu; 01151 unsigned int tfms, junk, cap, capamd; 01152 01153 signal(SIGILL, model3); 01154 01155 if (sigsetjmp(jenv, 1)) 01156 return 3; 01157 01158 if (cpuid_eax(0x000000000)==0) 01159 return 4; 01160 01161 cpuid(0x00000001, &tfms, &junk, &junk, &cap); 01162 cpuid(0x80000001, &junk, &junk, &junk, &capamd); 01163 01164 cpu = (tfms>>8)&15; 01165 01166 if (cpu < 6) 01167 return cpu; 01168 01169 if (cap & (1<<15)) { 01170 /* CMOV supported? */ 01171 if (capamd & (1<<30)) 01172 return 7; /* 3DNOWEXT supported */ 01173 return 6; 01174 } 01175 01176 return 5; 01177 } 01178 01179 /* should only be called for model 6 CPU's */ 01180 static int is_athlon(void) 01181 /*@*/ 01182 { 01183 unsigned int eax, ebx, ecx, edx; 01184 char vendor[16]; 01185 int i; 01186 01187 cpuid (0, &eax, &ebx, &ecx, &edx); 01188 01189 /* If you care about space, you can just check ebx, ecx and edx directly 01190 instead of forming a string first and then doing a strcmp */ 01191 memset(vendor, 0, sizeof(vendor)); 01192 01193 for (i=0; i<4; i++) 01194 vendor[i] = (unsigned char) (ebx >>(8*i)); 01195 for (i=0; i<4; i++) 01196 vendor[4+i] = (unsigned char) (edx >>(8*i)); 01197 for (i=0; i<4; i++) 01198 vendor[8+i] = (unsigned char) (ecx >>(8*i)); 01199 01200 if (strncmp(vendor, "AuthenticAMD", 12) != 0) 01201 return 0; 01202 01203 return 1; 01204 } 01205 01206 static int is_pentium3(void) 01207 { 01208 unsigned int eax, ebx, ecx, edx, family, model; 01209 char vendor[16]; 01210 cpuid(0, &eax, &ebx, &ecx, &edx); 01211 memset(vendor, 0, sizeof(vendor)); 01212 *((unsigned int *)&vendor[0]) = ebx; 01213 *((unsigned int *)&vendor[4]) = edx; 01214 *((unsigned int *)&vendor[8]) = ecx; 01215 if (strncmp(vendor, "GenuineIntel", 12) != 0) 01216 return 0; 01217 cpuid(1, &eax, &ebx, &ecx, &edx); 01218 family = (eax >> 8) & 0x0f; 01219 model = (eax >> 4) & 0x0f; 01220 if (family == 6) 01221 switch (model) 01222 { 01223 case 7: // Pentium III, Pentium III Xeon (model 7) 01224 case 8: // Pentium III, Pentium III Xeon, Celeron (model 8) 01225 case 9: // Pentium M 01226 /* 01227 Intel recently announced its new technology for mobile platforms, 01228 named Centrino, and presents it as a big advance in mobile PCs. 01229 One of the main part of Centrino consists in a brand new CPU, 01230 the Pentium M, codenamed Banias, that we'll study in this review. 01231 A particularity of this CPU is that it was designed for mobile platform 01232 exclusively, unlike previous mobile CPU (Pentium III-M, Pentium 4-M) 01233 that share the same micro-architecture as their desktop counterparts. 01234 The Pentium M introduces a new micro-architecture, adapted for mobility 01235 constraints, and that is halfway between the Pentium III and the Pentium 4. 01236 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 01237 */ 01238 case 10: // Pentium III Xeon (model A) 01239 case 11: // Pentium III (model B) 01240 return 1; 01241 } 01242 return 0; 01243 } 01244 01245 static int is_pentium4(void) 01246 { 01247 unsigned int eax, ebx, ecx, edx, family, model; 01248 char vendor[16]; 01249 cpuid(0, &eax, &ebx, &ecx, &edx); 01250 memset(vendor, 0, sizeof(vendor)); 01251 *((unsigned int *)&vendor[0]) = ebx; 01252 *((unsigned int *)&vendor[4]) = edx; 01253 *((unsigned int *)&vendor[8]) = ecx; 01254 if (strncmp(vendor, "GenuineIntel", 12) != 0) 01255 return 0; 01256 cpuid(1, &eax, &ebx, &ecx, &edx); 01257 family = (eax >> 8) & 0x0f; 01258 model = (eax >> 4) & 0x0f; 01259 if (family == 15) 01260 switch (model) 01261 { 01262 case 0: // Pentium 4, Pentium 4 Xeon (0.18um) 01263 case 1: // Pentium 4, Pentium 4 Xeon MP, Celeron (0.18um) 01264 case 2: // Pentium 4, Mobile Pentium 4-M, 01265 // Pentium 4 Xeon, Pentium 4 Xeon MP, 01266 // Celeron, Mobile Celron (0.13um) 01267 case 3: // Pentium 4, Celeron (0.09um) 01268 case 4: // Pentium 4 540J 01269 return 1; 01270 } 01271 return 0; 01272 } 01273 01274 #endif 01275 01276 #if defined(__linux__) && defined(__powerpc__) 01277 static jmp_buf mfspr_jmpbuf; 01278 01279 static void mfspr_ill(int notused) 01280 { 01281 longjmp(mfspr_jmpbuf, -1); 01282 } 01283 #endif 01284 01287 static void defaultMachine(/*@out@*/ const char ** arch, 01288 /*@out@*/ const char ** os) 01289 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 01290 /*@modifies *arch, *os, rpmGlobalMacroContext, fileSystem, internalState @*/ 01291 { 01292 static struct utsname un; 01293 static int gotDefaults = 0; 01294 char * chptr; 01295 canonEntry canon; 01296 int rc; 01297 01298 while (!gotDefaults) { 01299 CVOG_t cvog = NULL; 01300 rc = uname(&un); 01301 if (rc < 0) return; 01302 01303 if (!rpmPlatform(platform)) { 01304 const char * s; 01305 gotDefaults = 1; 01306 s = rpmExpand("%{?_host_cpu}", NULL); 01307 if (s && *s != '\0') { 01308 strncpy(un.machine, s, sizeof(un.machine)); 01309 un.machine[sizeof(un.machine)-1] = '\0'; 01310 } 01311 s = _free(s); 01312 s = rpmExpand("%{?_host_os}", NULL); 01313 if (s && *s != '\0') { 01314 strncpy(un.sysname, s, sizeof(un.sysname)); 01315 un.sysname[sizeof(un.sysname)-1] = '\0'; 01316 } 01317 s = _free(s); 01318 } 01319 01320 if (configTarget && !parseCVOG(configTarget, &cvog) && cvog != NULL) { 01321 gotDefaults = 1; 01322 if (cvog->cpu && cvog->cpu[0] != '\0') { 01323 strncpy(un.machine, cvog->cpu, sizeof(un.machine)); 01324 un.machine[sizeof(un.machine)-1] = '\0'; 01325 } 01326 if (cvog->os && cvog->os[0] != '\0') { 01327 strncpy(un.sysname, cvog->os, sizeof(un.sysname)); 01328 un.sysname[sizeof(un.sysname)-1] = '\0'; 01329 } 01330 cvog->str = _free(cvog->str); 01331 cvog = _free(cvog); 01332 } 01333 if (gotDefaults) 01334 break; 01335 01336 #if !defined(__linux__) 01337 #ifdef SNI 01338 /* USUALLY un.sysname on sinix does start with the word "SINIX" 01339 * let's be absolutely sure 01340 */ 01341 strncpy(un.sysname, "SINIX", sizeof(un.sysname)); 01342 #endif 01343 /*@-nullpass@*/ 01344 if (!strcmp(un.sysname, "AIX")) { 01345 strcpy(un.machine, __power_pc() ? "ppc" : "rs6000"); 01346 sprintf(un.sysname,"aix%s.%s", un.version, un.release); 01347 } 01348 else if(!strcmp(un.sysname, "Darwin")) { 01349 #ifdef __ppc__ 01350 strcpy(un.machine, "ppc"); 01351 #else ifdef __i386__ 01352 strcpy(un.machine, "i386"); 01353 #endif 01354 } 01355 else if (!strcmp(un.sysname, "SunOS")) { 01356 if (!strncmp(un.release,"4", 1)) /* SunOS 4.x */ { 01357 int fd; 01358 for (fd = 0; 01359 (un.release[fd] != 0 && (fd < sizeof(un.release))); 01360 fd++) { 01361 if (!xisdigit(un.release[fd]) && (un.release[fd] != '.')) { 01362 un.release[fd] = 0; 01363 /*@innerbreak@*/ break; 01364 } 01365 } 01366 sprintf(un.sysname,"sunos%s",un.release); 01367 } 01368 01369 else /* Solaris 2.x: n.x.x becomes n-3.x.x */ 01370 sprintf(un.sysname, "solaris%1d%s", atoi(un.release)-3, 01371 un.release+1+(atoi(un.release)/10)); 01372 01373 /* Solaris on Intel hardware reports i86pc instead of i386 01374 * (at least on 2.6 and 2.8) 01375 */ 01376 if (!strcmp(un.machine, "i86pc")) 01377 sprintf(un.machine, "i386"); 01378 } 01379 else if (!strcmp(un.sysname, "HP-UX")) 01380 /*make un.sysname look like hpux9.05 for example*/ 01381 sprintf(un.sysname, "hpux%s", strpbrk(un.release, "123456789")); 01382 else if (!strcmp(un.sysname, "OSF1")) 01383 /*make un.sysname look like osf3.2 for example*/ 01384 sprintf(un.sysname, "osf%s", strpbrk(un.release, "123456789")); 01385 else if (!strncmp(un.sysname, "IP", 2)) 01386 un.sysname[2] = '\0'; 01387 else if (!strncmp(un.sysname, "SINIX", 5)) { 01388 sprintf(un.sysname, "sinix%s",un.release); 01389 if (!strncmp(un.machine, "RM", 2)) 01390 sprintf(un.machine, "mips"); 01391 } 01392 else if ((!strncmp(un.machine, "34", 2) || 01393 !strncmp(un.machine, "33", 2)) && \ 01394 !strncmp(un.release, "4.0", 3)) 01395 { 01396 /* we are on ncr-sysv4 */ 01397 char * prelid = NULL; 01398 FD_t fd = Fopen("/etc/.relid", "r.fdio"); 01399 int gotit = 0; 01400 /*@-branchstate@*/ 01401 if (fd != NULL && !Ferror(fd)) { 01402 chptr = xcalloc(1, 256); 01403 { int irelid = Fread(chptr, sizeof(*chptr), 256, fd); 01404 (void) Fclose(fd); 01405 /* example: "112393 RELEASE 020200 Version 01 OS" */ 01406 if (irelid > 0) { 01407 if ((prelid = strstr(chptr, "RELEASE "))){ 01408 prelid += strlen("RELEASE ")+1; 01409 sprintf(un.sysname,"ncr-sysv4.%.*s",1,prelid); 01410 gotit = 1; 01411 } 01412 } 01413 } 01414 chptr = _free (chptr); 01415 } 01416 /*@=branchstate@*/ 01417 if (!gotit) /* parsing /etc/.relid file failed? */ 01418 strcpy(un.sysname,"ncr-sysv4"); 01419 /* wrong, just for now, find out how to look for i586 later*/ 01420 strcpy(un.machine,"i486"); 01421 } 01422 /*@=nullpass@*/ 01423 #endif /* __linux__ */ 01424 01425 /* get rid of the hyphens in the sysname */ 01426 for (chptr = un.machine; *chptr != '\0'; chptr++) 01427 if (*chptr == '/') *chptr = '-'; 01428 01429 # if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) 01430 /* little endian */ 01431 strcpy(un.machine, "mipsel"); 01432 # elif defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) 01433 /* big endian */ 01434 strcpy(un.machine, "mips"); 01435 # endif 01436 01437 # if defined(__hpux) && defined(_SC_CPU_VERSION) 01438 { 01439 # if !defined(CPU_PA_RISC1_2) 01440 # define CPU_PA_RISC1_2 0x211 /* HP PA-RISC1.2 */ 01441 # endif 01442 # if !defined(CPU_PA_RISC2_0) 01443 # define CPU_PA_RISC2_0 0x214 /* HP PA-RISC2.0 */ 01444 # endif 01445 int cpu_version = sysconf(_SC_CPU_VERSION); 01446 01447 # if defined(CPU_HP_MC68020) 01448 if (cpu_version == CPU_HP_MC68020) 01449 strcpy(un.machine, "m68k"); 01450 # endif 01451 # if defined(CPU_HP_MC68030) 01452 if (cpu_version == CPU_HP_MC68030) 01453 strcpy(un.machine, "m68k"); 01454 # endif 01455 # if defined(CPU_HP_MC68040) 01456 if (cpu_version == CPU_HP_MC68040) 01457 strcpy(un.machine, "m68k"); 01458 # endif 01459 01460 # if defined(CPU_PA_RISC1_0) 01461 if (cpu_version == CPU_PA_RISC1_0) 01462 strcpy(un.machine, "hppa1.0"); 01463 # endif 01464 # if defined(CPU_PA_RISC1_1) 01465 if (cpu_version == CPU_PA_RISC1_1) 01466 strcpy(un.machine, "hppa1.1"); 01467 # endif 01468 # if defined(CPU_PA_RISC1_2) 01469 if (cpu_version == CPU_PA_RISC1_2) 01470 strcpy(un.machine, "hppa1.2"); 01471 # endif 01472 # if defined(CPU_PA_RISC2_0) 01473 if (cpu_version == CPU_PA_RISC2_0) 01474 strcpy(un.machine, "hppa2.0"); 01475 # endif 01476 } 01477 # endif /* hpux */ 01478 01479 # if defined(__linux__) && defined(__sparc__) 01480 if (!strcmp(un.machine, "sparc")) { 01481 #define PERS_LINUX 0x00000000 01482 #define PERS_LINUX_32BIT 0x00800000 01483 #define PERS_LINUX32 0x00000008 01484 01485 extern int personality(unsigned long); 01486 int oldpers; 01487 01488 oldpers = personality(PERS_LINUX_32BIT); 01489 if (oldpers != -1) { 01490 if (personality(PERS_LINUX) != -1) { 01491 uname(&un); 01492 if (! strcmp(un.machine, "sparc64")) { 01493 strcpy(un.machine, "sparcv9"); 01494 oldpers = PERS_LINUX32; 01495 } 01496 } 01497 personality(oldpers); 01498 } 01499 } 01500 # endif /* sparc*-linux */ 01501 01502 # if defined(__GNUC__) && defined(__alpha__) 01503 { 01504 unsigned long amask, implver; 01505 register long v0 __asm__("$0") = -1; 01506 __asm__ (".long 0x47e00c20" : "=r"(v0) : "0"(v0)); 01507 amask = ~v0; 01508 __asm__ (".long 0x47e03d80" : "=r"(v0)); 01509 implver = v0; 01510 switch (implver) { 01511 case 1: 01512 switch (amask) { 01513 case 0: strcpy(un.machine, "alphaev5"); break; 01514 case 1: strcpy(un.machine, "alphaev56"); break; 01515 case 0x101: strcpy(un.machine, "alphapca56"); break; 01516 } 01517 break; 01518 case 2: 01519 switch (amask) { 01520 case 0x303: strcpy(un.machine, "alphaev6"); break; 01521 case 0x307: strcpy(un.machine, "alphaev67"); break; 01522 } 01523 break; 01524 } 01525 } 01526 # endif 01527 01528 # if defined(__linux__) && defined(__i386__) 01529 { 01530 char class = (char) (RPMClass() | '0'); 01531 01532 if ((class == '6' && is_athlon()) || class == '7') 01533 strcpy(un.machine, "athlon"); 01534 else if (is_pentium4()) 01535 strcpy(un.machine, "pentium4"); 01536 else if (is_pentium3()) 01537 strcpy(un.machine, "pentium3"); 01538 else if (strchr("3456", un.machine[1]) && un.machine[1] != class) 01539 un.machine[1] = class; 01540 } 01541 # endif 01542 01543 # if defined(__linux__) && defined(__powerpc__) 01544 { 01545 unsigned pvr = 0; 01546 __sighandler_t oldh = signal(SIGILL, mfspr_ill); 01547 if (setjmp(mfspr_jmpbuf) == 0) { 01548 __asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr)); 01549 } 01550 signal(SIGILL, oldh); 01551 01552 if ( pvr ) { 01553 pvr >>= 16; 01554 switch (pvr) { 01555 /* IBM750FX, 7410, 7450, 7451, 7441, 7455, 7445 */ 01556 case 0x7000: 01557 case 0x8000: 01558 case 0x8001: 01559 case 0x800c: 01560 strcpy(un.machine, "ppc"); 01561 break; 01562 case 0x36: 01563 case 0x37: 01564 strcpy(un.machine, "ppciseries"); 01565 break; 01566 default: 01567 if ( pvr >= 0x40) 01568 strcpy(un.machine, "ppcpseries"); 01569 else 01570 strcpy(un.machine, "ppc"); 01571 break; 01572 } 01573 } 01574 } 01575 # endif 01576 01577 /* the uname() result goes through the arch_canon table */ 01578 canon = lookupInCanonTable(un.machine, 01579 tables[RPM_MACHTABLE_INSTARCH].canons, 01580 tables[RPM_MACHTABLE_INSTARCH].canonsLength); 01581 if (canon) 01582 strcpy(un.machine, canon->short_name); 01583 01584 canon = lookupInCanonTable(un.sysname, 01585 tables[RPM_MACHTABLE_INSTOS].canons, 01586 tables[RPM_MACHTABLE_INSTOS].canonsLength); 01587 if (canon) 01588 strcpy(un.sysname, canon->short_name); 01589 gotDefaults = 1; 01590 break; 01591 } 01592 01593 if (arch) *arch = un.machine; 01594 if (os) *os = un.sysname; 01595 } 01596 01597 void rpmSetTables(int archTable, int osTable) 01598 /*@globals currTables @*/ 01599 /*@modifies currTables @*/ 01600 { 01601 const char * arch, * os; 01602 01603 defaultMachine(&arch, &os); 01604 01605 if (currTables[ARCH] != archTable) { 01606 currTables[ARCH] = archTable; 01607 rebuildCompatTables(ARCH, arch); 01608 } 01609 01610 if (currTables[OS] != osTable) { 01611 currTables[OS] = osTable; 01612 rebuildCompatTables(OS, os); 01613 } 01614 } 01615 01616 int rpmMachineScore(int type, const char * name) 01617 { 01618 const char * fakeplatform; 01619 int score = 0; 01620 switch (type) { 01621 case RPM_MACHTABLE_INSTARCH: 01622 fakeplatform = rpmExpand(name, "%{_host_vendor}-%{_host_os}%{?_gnu}", NULL); 01623 break; 01624 case RPM_MACHTABLE_BUILDARCH: 01625 fakeplatform = rpmExpand(name, "%{_target_vendor}-%{_target_os}%{?_gnu}", NULL); 01626 break; 01627 case RPM_MACHTABLE_INSTOS: 01628 fakeplatform = rpmExpand("%{_host_arch}-%{_host_vendor}-", name, "%{?_gnu}", NULL); 01629 break; 01630 case RPM_MACHTABLE_BUILDOS: 01631 fakeplatform = rpmExpand("%{_target_arch}-%{_target_vendor}-", name, "%{?_gnu}", NULL); 01632 break; 01633 } 01634 score = rpmPlatformScore(fakeplatform, NULL, 0); 01635 _free(fakeplatform); 01636 return(score); 01637 } 01638 01639 /*@-modnomods@*/ 01640 void rpmGetMachine(const char ** arch, const char ** os) 01641 { 01642 if (arch) 01643 *arch = current[ARCH]; 01644 01645 if (os) 01646 *os = current[OS]; 01647 } 01648 /*@=modnomods@*/ 01649 01650 void rpmSetMachine(const char * arch, const char * os) 01651 /*@globals current @*/ 01652 /*@modifies current @*/ 01653 { 01654 if (arch == NULL) { 01655 /*@i@*/ defaultMachine(&arch, NULL); 01656 if (tables[currTables[ARCH]].hasTranslate) 01657 arch = lookupInDefaultTable(arch, 01658 tables[currTables[ARCH]].defaults, 01659 tables[currTables[ARCH]].defaultsLength); 01660 } 01661 assert(arch != NULL); 01662 01663 if (os == NULL) { 01664 /*@i@*/ defaultMachine(NULL, &os); 01665 if (tables[currTables[OS]].hasTranslate) 01666 os = lookupInDefaultTable(os, 01667 tables[currTables[OS]].defaults, 01668 tables[currTables[OS]].defaultsLength); 01669 } 01670 assert(os != NULL); 01671 01672 01673 if (!current[ARCH] || strcmp(arch, current[ARCH])) { 01674 current[ARCH] = _free(current[ARCH]); 01675 current[ARCH] = xstrdup(arch); 01676 rebuildCompatTables(ARCH, arch); 01677 } 01678 01679 if (!current[OS] || strcmp(os, current[OS])) { 01680 char * t = xstrdup(os); 01681 current[OS] = _free(current[OS]); 01682 if (!strcmp(t, "linux")) 01683 *t = 'L'; 01684 current[OS] = t; 01685 rebuildCompatTables(OS, os); 01686 } 01687 } 01688 01689 static void getMachineInfo(int type, /*@null@*/ /*@out@*/ const char ** name, 01690 /*@null@*/ /*@out@*/int * num) 01691 /*@modifies *name, *num @*/ 01692 { 01693 canonEntry canon; 01694 int which = currTables[type]; 01695 01696 /* use the normal canon tables, even if we're looking up build stuff */ 01697 if (which >= 2) which -= 2; 01698 01699 canon = lookupInCanonTable(current[type], 01700 tables[which].canons, 01701 tables[which].canonsLength); 01702 01703 if (canon) { 01704 if (num) *num = canon->num; 01705 if (name) *name = canon->short_name; 01706 } else { 01707 if (num) *num = 255; 01708 if (name) *name = current[type]; 01709 } 01710 } 01711 01712 void rpmGetArchInfo(const char ** name, int * num) 01713 { 01714 getMachineInfo(ARCH, name, num); 01715 } 01716 01717 void rpmGetOsInfo(const char ** name, int * num) 01718 { 01719 getMachineInfo(OS, name, num); 01720 } 01721 01722 static void rpmRebuildTargetVars(const char ** target, const char ** canontarget) 01723 { 01724 01725 char *ca = NULL, *co = NULL, *ct = NULL; 01726 int x; 01727 01728 /* Rebuild the compat table to recalculate the current target arch. */ 01729 01730 rpmSetMachine(NULL, NULL); 01731 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS); 01732 rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS); 01733 01734 /*@-branchstate@*/ 01735 if (target && *target) { 01736 char *c; 01737 /* Set arch and os from specified build target */ 01738 ca = xstrdup(*target); 01739 if ((c = strchr(ca, '-')) != NULL) { 01740 *c++ = '\0'; 01741 01742 if ((co = strrchr(c, '-')) == NULL) { 01743 co = c; 01744 } else { 01745 if (!xstrcasecmp(co, "-gnu")) 01746 *co = '\0'; 01747 if ((co = strrchr(c, '-')) == NULL) 01748 co = c; 01749 else 01750 co++; 01751 } 01752 if (co != NULL) co = xstrdup(co); 01753 } 01754 } else { 01755 const char *a = NULL; 01756 const char *o = NULL; 01757 /* Set build target from rpm arch and os */ 01758 getMachineInfo(ARCH, &a, NULL); 01759 ca = (a) ? xstrdup(a) : NULL; 01760 getMachineInfo(OS, &o, NULL); 01761 co = (o) ? xstrdup(o) : NULL; 01762 } 01763 /*@=branchstate@*/ 01764 01765 /* If still not set, Set target arch/os from default uname(2) values */ 01766 if (ca == NULL) { 01767 const char *a = NULL; 01768 defaultMachine(&a, NULL); 01769 ca = (a) ? xstrdup(a) : NULL; 01770 } 01771 if (ca != NULL) 01772 for (x = 0; ca[x] != '\0'; x++) 01773 ca[x] = xtolower(ca[x]); 01774 01775 if (co == NULL) { 01776 const char *o = NULL; 01777 defaultMachine(NULL, &o); 01778 co = (o) ? xstrdup(o) : NULL; 01779 } 01780 if (co != NULL) 01781 for (x = 0; co[x] != '\0'; x++) 01782 co[x] = xtolower(co[x]); 01783 01784 /* XXX For now, set canonical target to arch-os */ 01785 if (ct == NULL) { 01786 ct = xmalloc(strlen(ca) + sizeof("-") + strlen(co)); 01787 sprintf(ct, "%s-%s", ca, co); 01788 } 01789 01790 /* 01791 * XXX All this macro pokery/jiggery could be achieved by doing a delayed 01792 * rpmInitMacros(NULL, PER-PLATFORM-MACRO-FILE-NAMES); 01793 */ 01794 delMacro(NULL, "_target"); 01795 addMacro(NULL, "_target", NULL, ct, RMIL_RPMRC); 01796 delMacro(NULL, "_target_cpu"); 01797 addMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC); 01798 delMacro(NULL, "_target_os"); 01799 addMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC); 01800 /* 01801 * XXX Make sure that per-arch optflags is initialized correctly. 01802 */ 01803 if (rpmcliRcfile != NULL) 01804 { const char *optflags = rpmGetVarArch(RPMVAR_OPTFLAGS, ca); 01805 if (optflags != NULL) { 01806 delMacro(NULL, "optflags"); 01807 addMacro(NULL, "optflags", NULL, optflags, RMIL_RPMRC); 01808 } 01809 } 01810 01811 /*@-branchstate@*/ 01812 if (canontarget) 01813 *canontarget = ct; 01814 else 01815 ct = _free(ct); 01816 /*@=branchstate@*/ 01817 ca = _free(ca); 01818 /*@-usereleased@*/ 01819 co = _free(co); 01820 /*@=usereleased@*/ 01821 } 01822 01823 void rpmFreeRpmrc(void) 01824 /*@globals current, tables, values, defaultsInitialized @*/ 01825 /*@modifies current, tables, values, defaultsInitialized @*/ 01826 { 01827 int i, j, k; 01828 01829 platpat = mireFreeAll(platpat, nplatpat); 01830 nplatpat = 0; 01831 01832 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) { 01833 tableType t; 01834 t = tables + i; 01835 if (t->equiv.list) { 01836 for (j = 0; j < t->equiv.count; j++) 01837 t->equiv.list[j].name = _free(t->equiv.list[j].name); 01838 t->equiv.list = _free(t->equiv.list); 01839 t->equiv.count = 0; 01840 } 01841 if (t->cache.cache) { 01842 for (j = 0; j < t->cache.size; j++) { 01843 machCacheEntry e; 01844 e = t->cache.cache + j; 01845 if (e == NULL) 01846 /*@innercontinue@*/ continue; 01847 e->name = _free(e->name); 01848 if (e->equivs) { 01849 for (k = 0; k < e->count; k++) 01850 e->equivs[k] = _free(e->equivs[k]); 01851 e->equivs = _free(e->equivs); 01852 } 01853 } 01854 t->cache.cache = _free(t->cache.cache); 01855 t->cache.size = 0; 01856 } 01857 if (t->defaults) { 01858 for (j = 0; j < t->defaultsLength; j++) { 01859 t->defaults[j].name = _free(t->defaults[j].name); 01860 t->defaults[j].defName = _free(t->defaults[j].defName); 01861 } 01862 t->defaults = _free(t->defaults); 01863 t->defaultsLength = 0; 01864 } 01865 if (t->canons) { 01866 for (j = 0; j < t->canonsLength; j++) { 01867 t->canons[j].name = _free(t->canons[j].name); 01868 t->canons[j].short_name = _free(t->canons[j].short_name); 01869 } 01870 t->canons = _free(t->canons); 01871 t->canonsLength = 0; 01872 } 01873 } 01874 01875 for (i = 0; i < RPMVAR_NUM; i++) { 01876 /*@only@*/ /*@null@*/ struct rpmvarValue * vp; 01877 while ((vp = values[i].next) != NULL) { 01878 values[i].next = vp->next; 01879 vp->value = _free(vp->value); 01880 vp->arch = _free(vp->arch); 01881 vp = _free(vp); 01882 } 01883 values[i].value = _free(values[i].value); 01884 values[i].arch = _free(values[i].arch); 01885 } 01886 current[OS] = _free(current[OS]); 01887 current[ARCH] = _free(current[ARCH]); 01888 defaultsInitialized = 0; 01889 /*@-globstate -nullstate@*/ /* FIX: platpat/current may be NULL */ 01890 return; 01891 /*@=globstate =nullstate@*/ 01892 } 01893 01899 static int rpmReadRC(/*@null@*/ const char * rcfiles) 01900 /*@globals defaultsInitialized, rpmRcfiles, rpmMacrofiles, 01901 rpmGlobalMacroContext, rpmCLIMacroContext, h_errno, 01902 fileSystem, internalState @*/ 01903 /*@modifies defaultsInitialized, rpmGlobalMacroContext, 01904 fileSystem, internalState @*/ 01905 { 01906 char *myrcfiles = NULL; 01907 char *r, *re; 01908 int rc; 01909 01910 if (!defaultsInitialized) { 01911 setDefaults(); 01912 defaultsInitialized = 1; 01913 } 01914 01915 /* Read each file in rcfiles. */ 01916 rc = 0; 01917 if (rcfiles != NULL) 01918 for (r = myrcfiles = xstrdup(rcfiles); r && *r != '\0'; r = re) { 01919 char fn[4096]; 01920 FD_t fd; 01921 01922 /* Get pointer to rest of files */ 01923 for (re = r; (re = strchr(re, ':')) != NULL; re++) { 01924 if (!(re[1] == '/' && re[2] == '/')) 01925 /*@innerbreak@*/ break; 01926 } 01927 if (re && *re == ':') 01928 *re++ = '\0'; 01929 else 01930 re = r + strlen(r); 01931 01932 /* Expand ~/ to $HOME/ */ 01933 fn[0] = '\0'; 01934 if (r[0] == '~' && r[1] == '/') { 01935 const char * etc_dir = getenv("HOME_ETC"); 01936 const char * home = getenv("HOME"); 01937 if (etc_dir) { 01938 if (strlen(etc_dir) > (sizeof(fn) - strlen(r))) { 01939 rpmError(RPMERR_RPMRC, _("Cannot read %s, HOME_ETC is too large.\n"),r); 01940 rc = 1; 01941 break; 01942 } 01943 strcpy(fn, etc_dir); 01944 strncat(fn, "/", sizeof(fn) - strlen(fn)); 01945 r+=2; 01946 } else { 01947 if (home == NULL) { 01948 /* XXX Only /usr/lib/rpm/rpmrc must exist in default rcfiles list */ 01949 if (rcfiles == rpmRcfiles && myrcfiles != r) 01950 continue; 01951 rpmError(RPMERR_RPMRC, _("Cannot expand %s\n"), r); 01952 rc = 1; 01953 break; 01954 } 01955 if (strlen(home) > (sizeof(fn) - strlen(r))) { 01956 rpmError(RPMERR_RPMRC, _("Cannot read %s, HOME is too large.\n"), 01957 r); 01958 rc = 1; 01959 break; 01960 } 01961 strcpy(fn, home); 01962 r++; 01963 } 01964 01965 01966 } 01967 strncat(fn, r, sizeof(fn) - (strlen(fn) + 1)); 01968 fn[sizeof(fn)-1] = '\0'; 01969 01970 /* Read another rcfile */ 01971 fd = Fopen(fn, "r.fpio"); 01972 if (fd == NULL || Ferror(fd)) { 01973 /* XXX Only /usr/lib/rpm/rpmrc must exist in default rcfiles list */ 01974 if (rcfiles == rpmRcfiles && myrcfiles != r) 01975 continue; 01976 rpmError(RPMERR_RPMRC, _("Unable to open %s for reading: %s.\n"), 01977 fn, Fstrerror(fd)); 01978 rc = 1; 01979 break; 01980 } else { 01981 rc = doReadRC(fd, fn); 01982 } 01983 if (rc) break; 01984 } 01985 myrcfiles = _free(myrcfiles); 01986 if (rc) 01987 return rc; 01988 01989 /* Read macro files. */ 01990 { const char *mfpath = rpmGetVarArch(RPMVAR_MACROFILES, NULL); 01991 01992 if (mfpath == NULL) 01993 mfpath = rpmExpand(rpmMacrofiles, NULL); 01994 else 01995 mfpath = xstrdup(mfpath); 01996 01997 /*@-branchstate@*/ 01998 if (mfpath != NULL) { 01999 rpmInitMacros(NULL, mfpath); 02000 mfpath = _free(mfpath); 02001 } 02002 /*@=branchstate@*/ 02003 } 02004 02005 return rc; 02006 } 02007 02008 int rpmReadConfigFiles(const char * file, const char * target) 02009 /*@globals configTarget @*/ 02010 /*@modifies configTarget @*/ 02011 { 02012 02013 configTarget = target; 02014 02015 /* Preset target macros */ 02016 /*@-nullstate@*/ /* FIX: target can be NULL */ 02017 rpmRebuildTargetVars(&target, NULL); 02018 02019 /* Read the files */ 02020 /*@-globs@*/ 02021 if (rpmReadRC(file)) return -1; 02022 /*@=globs@*/ 02023 02024 /* Reset target macros */ 02025 rpmRebuildTargetVars(&target, NULL); 02026 /*@=nullstate@*/ 02027 02028 /* Finally set target platform */ 02029 { const char *cpu = rpmExpand("%{_target_cpu}", NULL); 02030 const char *os = rpmExpand("%{_target_os}", NULL); 02031 rpmSetMachine(cpu, os); 02032 cpu = _free(cpu); 02033 os = _free(os); 02034 } 02035 configTarget = NULL; 02036 02037 /* Force Lua state initialization */ 02038 #ifdef WITH_LUA 02039 (void)rpmluaGetPrintBuffer(NULL); 02040 #endif 02041 02042 return 0; 02043 } 02044 02045 int rpmShowRC(FILE * fp) 02046 { 02047 rpmds ds = NULL; 02048 struct rpmOption *opt; 02049 int i; 02050 machEquivTable equivTable; 02051 int xx; 02052 02053 /* the caller may set the build arch which should be printed here */ 02054 fprintf(fp, "ARCHITECTURE AND OS:\n"); 02055 fprintf(fp, "build arch : %s\n", current[ARCH]); 02056 02057 fprintf(fp, "compatible build archs:"); 02058 equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv; 02059 for (i = 0; i < equivTable->count; i++) 02060 fprintf(fp," %s", equivTable->list[i].name); 02061 fprintf(fp, "\n"); 02062 02063 fprintf(fp, "build os : %s\n", current[OS]); 02064 02065 fprintf(fp, "compatible build os's :"); 02066 equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv; 02067 for (i = 0; i < equivTable->count; i++) 02068 fprintf(fp," %s", equivTable->list[i].name); 02069 fprintf(fp, "\n"); 02070 02071 if (rpmcliRcfile != NULL) { 02072 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS); 02073 rpmSetMachine(NULL, NULL); /* XXX WTFO? Why bother? */ 02074 } 02075 02076 fprintf(fp, "install arch : %s\n", current[ARCH]); 02077 fprintf(fp, "install os : %s\n", current[OS]); 02078 02079 fprintf(fp, "compatible archs :"); 02080 equivTable = &tables[RPM_MACHTABLE_INSTARCH].equiv; 02081 for (i = 0; i < equivTable->count; i++) 02082 fprintf(fp," %s", equivTable->list[i].name); 02083 fprintf(fp, "\n"); 02084 02085 fprintf(fp, "compatible os's :"); 02086 equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv; 02087 for (i = 0; i < equivTable->count; i++) 02088 fprintf(fp," %s", equivTable->list[i].name); 02089 fprintf(fp, "\n"); 02090 02091 if (rpmcliRcfile != NULL) { 02092 const char * s = rpmExpand(rpmcliRcfile, NULL); 02093 fprintf(fp, "\nRPMRC VALUES:\n"); 02094 fprintf(fp, "%-21s : %s\n", "rcfiles", ((s && *s) ? s : "(not set)")); 02095 s = _free(s); 02096 /*@-branchstate@*/ 02097 for (i = 0, opt = optionTable; i < optionTableSize; i++, opt++) { 02098 s = rpmGetVarArch(opt->var, NULL); 02099 if (s != NULL || rpmIsVerbose()) 02100 fprintf(fp, "%-21s : %s\n", opt->name, s ? s : "(not set)"); 02101 } 02102 /*@=branchstate@*/ 02103 fprintf(fp, "\nMACRO DEFINITIONS:\n"); 02104 } else { 02105 const char * s = rpmExpand("%{?optflags}", NULL); 02106 fprintf(fp, "%-21s : %s\n", "optflags", ((s && *s) ? s : "(not set)")); 02107 s = _free(s); 02108 /*@-globs@*/ 02109 s = rpmExpand(rpmMacrofiles, NULL); 02110 /*@=globs@*/ 02111 fprintf(fp, "\nMACRO DEFINITIONS:\n"); 02112 fprintf(fp, "%-21s : %s\n", "macrofiles", ((s && *s) ? s : "(not set)")); 02113 s = _free(s); 02114 } 02115 02116 if (rpmIsVerbose()) { 02117 rpmPRCO PRCO = rpmdsNewPRCO(NULL); 02118 xx = rpmdsSysinfo(PRCO, NULL); 02119 ds = rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME); 02120 if (ds != NULL) { 02121 fprintf(fp, _("Configured system provides (from /etc/rpm/sysinfo):\n")); 02122 ds = rpmdsInit(ds); 02123 while (rpmdsNext(ds) >= 0) { 02124 const char * DNEVR = rpmdsDNEVR(ds); 02125 if (DNEVR != NULL) 02126 fprintf(fp, " %s\n", DNEVR+2); 02127 } 02128 ds = rpmdsFree(ds); 02129 fprintf(fp, "\n"); 02130 } 02131 PRCO = rpmdsFreePRCO(PRCO); 02132 } 02133 02134 if (rpmIsVerbose()) { 02135 fprintf(fp, _("Features provided by rpmlib installer:\n")); 02136 xx = rpmdsRpmlib(&ds, NULL); 02137 ds = rpmdsInit(ds); 02138 while (rpmdsNext(ds) >= 0) { 02139 const char * DNEVR = rpmdsDNEVR(ds); 02140 if (DNEVR != NULL) 02141 fprintf(fp, " %s\n", DNEVR+2); 02142 } 02143 ds = rpmdsFree(ds); 02144 fprintf(fp, "\n"); 02145 02146 xx = rpmdsCpuinfo(&ds, NULL); 02147 if (ds != NULL) { 02148 fprintf(fp, 02149 _("Features provided by current cpuinfo (from /proc/cpuinfo):\n")); 02150 ds = rpmdsInit(ds); 02151 while (rpmdsNext(ds) >= 0) { 02152 const char * DNEVR = rpmdsDNEVR(ds); 02153 if (DNEVR != NULL) 02154 fprintf(fp, " %s\n", DNEVR+2); 02155 } 02156 ds = rpmdsFree(ds); 02157 fprintf(fp, "\n"); 02158 } 02159 } 02160 02161 if (rpmIsDebug()) { 02162 xx = rpmdsGetconf(&ds, NULL); 02163 if (ds != NULL) { 02164 fprintf(fp, 02165 _("Features provided by current getconf:\n")); 02166 ds = rpmdsInit(ds); 02167 while (rpmdsNext(ds) >= 0) { 02168 const char * DNEVR = rpmdsDNEVR(ds); 02169 if (DNEVR != NULL) 02170 fprintf(fp, " %s\n", DNEVR+2); 02171 } 02172 ds = rpmdsFree(ds); 02173 fprintf(fp, "\n"); 02174 } 02175 02176 xx = rpmdsUname(&ds, NULL); 02177 if (ds != NULL) { 02178 fprintf(fp, 02179 _("Features provided by current uname:\n")); 02180 ds = rpmdsInit(ds); 02181 while (rpmdsNext(ds) >= 0) { 02182 const char * DNEVR = rpmdsDNEVR(ds); 02183 if (DNEVR != NULL) 02184 fprintf(fp, " %s\n", DNEVR+2); 02185 } 02186 ds = rpmdsFree(ds); 02187 fprintf(fp, "\n"); 02188 } 02189 } 02190 02191 rpmDumpMacroTable(NULL, fp); 02192 02193 return 0; 02194 } 02195 /*@=bounds@*/