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
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
00036
00037
00038 static const char * configTarget = NULL;
00039
00040
00041 static const char * platform = SYSCONFIGDIR "/platform";
00042
00043
00044 void * platpat = NULL;
00045
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 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 const char * name;
00091 const char * defName;
00092 } * defaultEntry;
00093
00094 typedef struct canonEntry_s {
00095 const char * name;
00096 const char * short_name;
00097 short num;
00098 } * canonEntry;
00099
00100
00101
00102
00103
00104 typedef struct tableType_s {
00105 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
00117
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
00125
00126 #define OS 0
00127 #define ARCH 1
00128
00129
00130 static cptr_t current[2];
00131
00132
00133 static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH };
00134
00135
00136 static int defaultsInitialized = 0;
00137
00138
00139 static void rpmRebuildTargetVars( const char **target, const char ** canontarget)
00140
00141
00142 ;
00143
00144 static 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
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
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
00207
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
00226
00227
00228
00229
00230 machAddEquiv(table, key, 1);
00231 machCacheEntryVisit(cache, table, key, 2);
00232 return;
00233
00234 }
00235
00236 static 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
00245 return &(table[tableLen]);
00246
00247 }
00248
00249 return NULL;
00250 }
00251
00252 static
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, const char * body)
00268
00269
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
00278
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
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
00310 extern const char * __usrlibrpm;
00311
00312 extern const char * __etcrpm;
00313 #endif
00314
00315 static void setDefaults(void)
00316
00317
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
00361 const char * str;
00362
00363 const char * cpu;
00364
00365 const char * vendor;
00366
00367 const char * os;
00368
00369 const char * gnu;
00370 } * CVOG_t;
00371
00374 static int parseCVOG(const char * str, CVOG_t *cvogp)
00375
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
00431 static rpmRC rpmPlatform(const char * platform)
00432
00433
00434
00435
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)
00481
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
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
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
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
00662
00665 static void defaultMachine( const char ** arch,
00666 const char ** os)
00667
00668
00669 {
00670 #if defined(RPM_VENDOR_OPENPKG)
00671
00672
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)
00695 const char *cp;
00696 #endif
00697 #if defined(RPM_VENDOR_OPENPKG)
00698
00699
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)
00712
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
00722 cpR[n] = '\0';
00723
00724 if ((cp = strchr(cpR, '.')) != NULL) {
00725 if ((cp = strchr(cp+1, '.')) != NULL)
00726 *cp = '\0';
00727 }
00728 strcat(un.sysname, cpR);
00729 }
00730
00731
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)
00742
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 const char * s;
00753 gotDefaults = 1;
00754 s = rpmExpand("%{?_host_cpu}", NULL);
00755 if (s && *s != '\0') {
00756 strncpy(un.machine, s, sizeof(un.machine));
00757 un.machine[sizeof(un.machine)-1] = '\0';
00758 }
00759 s = _free(s);
00760 s = rpmExpand("%{?_host_os}", NULL);
00761 if (s && *s != '\0') {
00762 strncpy(un.sysname, s, sizeof(un.sysname));
00763 un.sysname[sizeof(un.sysname)-1] = '\0';
00764 }
00765 s = _free(s);
00766 }
00767
00768 #if defined(RPM_VENDOR_OPENPKG)
00769
00770 if (cp != NULL && cp != _platform)
00771 cp = _free(cp);
00772 #endif
00773 #if defined(RPM_VENDOR_WINDRIVER)
00774 _platform = _free(_platform);
00775 #endif
00776
00777 if (configTarget && !parseCVOG(configTarget, &cvog) && cvog != NULL) {
00778 gotDefaults = 1;
00779 if (cvog->cpu && cvog->cpu[0] != '\0') {
00780 strncpy(un.machine, cvog->cpu, sizeof(un.machine));
00781 un.machine[sizeof(un.machine)-1] = '\0';
00782 }
00783 if (cvog->os && cvog->os[0] != '\0') {
00784 strncpy(un.sysname, cvog->os, sizeof(un.sysname));
00785 un.sysname[sizeof(un.sysname)-1] = '\0';
00786 }
00787 cvog->str = _free(cvog->str);
00788 cvog = _free(cvog);
00789 }
00790 if (gotDefaults)
00791 break;
00792 gotDefaults = 1;
00793 break;
00794 }
00795
00796 if (arch) *arch = un.machine;
00797 if (os) *os = un.sysname;
00798 }
00799
00807 static void rpmSetTables(int archTable, int osTable)
00808
00809
00810
00811
00812 {
00813 const char * arch, * os;
00814
00815 defaultMachine(&arch, &os);
00816
00817 if (currTables[ARCH] != archTable) {
00818 currTables[ARCH] = archTable;
00819 rebuildCompatTables(ARCH, arch);
00820 }
00821
00822 if (currTables[OS] != osTable) {
00823 currTables[OS] = osTable;
00824 rebuildCompatTables(OS, os);
00825 }
00826 }
00827
00828 static void rpmSetMachine(const char * arch, const char * os)
00829
00830
00831
00832
00833 {
00834 if (arch == NULL) {
00835 defaultMachine(&arch, NULL);
00836 if (tables[currTables[ARCH]].hasTranslate)
00837 arch = lookupInDefaultTable(arch,
00838 tables[currTables[ARCH]].defaults,
00839 tables[currTables[ARCH]].defaultsLength);
00840 }
00841 assert(arch != NULL);
00842
00843 if (os == NULL) {
00844 defaultMachine(NULL, &os);
00845 if (tables[currTables[OS]].hasTranslate)
00846 os = lookupInDefaultTable(os,
00847 tables[currTables[OS]].defaults,
00848 tables[currTables[OS]].defaultsLength);
00849 }
00850 assert(os != NULL);
00851
00852
00853 if (!current[ARCH] || strcmp(arch, current[ARCH])) {
00854 current[ARCH] = _free(current[ARCH]);
00855 current[ARCH] = xstrdup(arch);
00856 rebuildCompatTables(ARCH, arch);
00857 }
00858
00859 if (!current[OS] || strcmp(os, current[OS])) {
00860 char * t = xstrdup(os);
00861 current[OS] = _free(current[OS]);
00862 if (!strcmp(t, "linux"))
00863 *t = 'L';
00864 current[OS] = t;
00865 rebuildCompatTables(OS, os);
00866 }
00867 }
00868
00869 static void getMachineInfo(int type, const char ** name,
00870 int * num)
00871
00872 {
00873 canonEntry canon;
00874 int which = currTables[type];
00875
00876
00877 if (which >= 2) which -= 2;
00878
00879 canon = lookupInCanonTable(current[type],
00880 tables[which].canons,
00881 tables[which].canonsLength);
00882
00883 if (canon) {
00884 if (num) *num = canon->num;
00885 if (name) *name = canon->short_name;
00886 } else {
00887 if (num) *num = 255;
00888 #if defined(WITH_CPUINFO)
00889 if (name)
00890 {
00891 if(type == ARCH)
00892 {
00893 int i, j, n;
00894 ARGV_t archs = NULL;
00895 char *pref = rpmExpand("%{?_prefer_target_cpu}", NULL);
00896
00897 (void) argvSplit(&archs, pref, " ");
00898 for(i = 0, n = argvCount(archs); (i < n && !*name); i++)
00899 if((j = rpmPlatformScore(archs[i], platpat, nplatpat)) > 0)
00900 *name = ((miRE)platpat)[j-1].pattern;
00901
00902 archs = argvFree(archs);
00903 pref = _free(pref);
00904 }
00905 if(!*name) *name = current[type];
00906 }
00907 #else
00908 if (name) *name = current[type];
00909 #endif
00910 }
00911 }
00912
00913 static void rpmRebuildTargetVars(const char ** target, const char ** canontarget)
00914 {
00915
00916 char *ca = NULL, *co = NULL, *ct = NULL;
00917 int x;
00918
00919
00920
00921 rpmSetMachine(NULL, NULL);
00922 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS);
00923 rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
00924
00925 if (target && *target) {
00926 char *c;
00927
00928 ca = xstrdup(*target);
00929 if ((c = strchr(ca, '-')) != NULL) {
00930 *c++ = '\0';
00931
00932 if ((co = strrchr(c, '-')) == NULL) {
00933 co = c;
00934 } else {
00935 if (!xstrcasecmp(co, "-gnu"))
00936 *co = '\0';
00937 if ((co = strrchr(c, '-')) == NULL)
00938 co = c;
00939 else
00940 co++;
00941 }
00942 if (co != NULL) co = xstrdup(co);
00943 }
00944 } else {
00945 const char *a = NULL;
00946 const char *o = NULL;
00947
00948 getMachineInfo(ARCH, &a, NULL);
00949 ca = (a) ? xstrdup(a) : NULL;
00950 getMachineInfo(OS, &o, NULL);
00951 co = (o) ? xstrdup(o) : NULL;
00952 }
00953
00954
00955 if (ca == NULL) {
00956 const char *a = NULL;
00957 defaultMachine(&a, NULL);
00958 ca = (a) ? xstrdup(a) : NULL;
00959 }
00960 if (ca != NULL)
00961 for (x = 0; ca[x] != '\0'; x++)
00962 ca[x] = (char)xtolower(ca[x]);
00963
00964 if (co == NULL) {
00965 const char *o = NULL;
00966 defaultMachine(NULL, &o);
00967 co = (o) ? xstrdup(o) : NULL;
00968 }
00969 if (co != NULL)
00970 for (x = 0; co[x] != '\0'; x++)
00971 co[x] = (char)xtolower(co[x]);
00972
00973
00974 if (ct == NULL) {
00975 ct = xmalloc(strlen(ca) + sizeof("-") + strlen(co));
00976 sprintf(ct, "%s-%s", ca, co);
00977 }
00978
00979
00980
00981
00982
00983 delMacro(NULL, "_target");
00984 addMacro(NULL, "_target", NULL, ct, RMIL_RPMRC);
00985 delMacro(NULL, "_target_cpu");
00986 addMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC);
00987 delMacro(NULL, "_target_os");
00988 addMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC);
00989
00990 if (canontarget)
00991 *canontarget = ct;
00992 else
00993 ct = _free(ct);
00994 ca = _free(ca);
00995
00996 co = _free(co);
00997
00998 }
00999
01000 void rpmFreeRpmrc(void)
01001
01002
01003 {
01004 int i, j, k;
01005
01006 (void)mireFreeAll(platpat, nplatpat);
01007 platpat = NULL;
01008 nplatpat = 0;
01009
01010 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
01011 tableType t;
01012 t = tables + i;
01013 if (t->equiv.list) {
01014 for (j = 0; j < t->equiv.count; j++)
01015 t->equiv.list[j].name = _free(t->equiv.list[j].name);
01016 t->equiv.list = _free(t->equiv.list);
01017 t->equiv.count = 0;
01018 }
01019 if (t->cache.cache) {
01020 for (j = 0; j < t->cache.size; j++) {
01021 machCacheEntry e;
01022 e = t->cache.cache + j;
01023 if (e == NULL)
01024 continue;
01025 e->name = _free(e->name);
01026 if (e->equivs) {
01027 for (k = 0; k < e->count; k++)
01028 e->equivs[k] = _free(e->equivs[k]);
01029 e->equivs = _free(e->equivs);
01030 }
01031 }
01032 t->cache.cache = _free(t->cache.cache);
01033 t->cache.size = 0;
01034 }
01035 if (t->defaults) {
01036 for (j = 0; j < t->defaultsLength; j++) {
01037 t->defaults[j].name = _free(t->defaults[j].name);
01038 t->defaults[j].defName = _free(t->defaults[j].defName);
01039 }
01040 t->defaults = _free(t->defaults);
01041 t->defaultsLength = 0;
01042 }
01043 if (t->canons) {
01044 for (j = 0; j < t->canonsLength; j++) {
01045 t->canons[j].name = _free(t->canons[j].name);
01046 t->canons[j].short_name = _free(t->canons[j].short_name);
01047 }
01048 t->canons = _free(t->canons);
01049 t->canonsLength = 0;
01050 }
01051 }
01052
01053 current[OS] = _free(current[OS]);
01054 current[ARCH] = _free(current[ARCH]);
01055 defaultsInitialized = 0;
01056
01057 return;
01058
01059 }
01060
01065 static int rpmReadRC(const char *macrofiles)
01066
01067
01068
01069
01070
01071 {
01072 int rc = 0;
01073
01074 if (!defaultsInitialized) {
01075 setDefaults();
01076 defaultsInitialized = 1;
01077 }
01078
01079
01080 { const char *mfpath = rpmExpand(macrofiles, NULL);
01081
01082 if (mfpath != NULL) {
01083 rpmInitMacros(NULL, mfpath);
01084 mfpath = _free(mfpath);
01085 }
01086 }
01087
01088 return rc;
01089 }
01090
01091 int rpmReadConfigFiles( const char * file,
01092 const char * target)
01093
01094
01095 {
01096 mode_t mode = 0022;
01097
01098 #ifdef PREMACROFILES
01099 if (rpmReadRC(PREMACROFILES)) return -1;
01100 #endif
01101
01102
01103 mode = umask(mode);
01104
01105 configTarget = target;
01106
01107
01108
01109 rpmRebuildTargetVars(&target, NULL);
01110
01111
01112
01113 if (rpmReadRC(rpmMacrofiles)) return -1;
01114
01115
01116
01117 rpmRebuildTargetVars(&target, NULL);
01118
01119
01120
01121 { const char *cpu = rpmExpand("%{_target_cpu}", NULL);
01122 const char *os = rpmExpand("%{_target_os}", NULL);
01123 rpmSetMachine(cpu, os);
01124
01125 cpu = _free(cpu);
01126 os = _free(os);
01127 }
01128 configTarget = NULL;
01129
01130
01131 #ifdef WITH_LUA
01132 (void)rpmluaGetPrintBuffer(NULL);
01133 #if defined(RPM_VENDOR_OPENPKG)
01134 (void)rpmluaextActivate(rpmluaGetGlobalState());
01135 #endif
01136 #endif
01137
01138 return 0;
01139 }
01140
01141 int rpmShowRC(FILE * fp)
01142 {
01143 rpmds ds = NULL;
01144 int i;
01145 machEquivTable equivTable;
01146 int xx;
01147 miRE mire;
01148
01149
01150 fprintf(fp, "ARCHITECTURE AND OS:\n");
01151 fprintf(fp, "build arch : %s\n", current[ARCH]);
01152
01153 fprintf(fp, "compatible build archs:");
01154 equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv;
01155 for (i = 0; i < equivTable->count; i++)
01156 fprintf(fp," %s", equivTable->list[i].name);
01157 fprintf(fp, "\n");
01158
01159 fprintf(fp, "build os : %s\n", current[OS]);
01160
01161 fprintf(fp, "compatible build os's :");
01162 equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv;
01163 for (i = 0; i < equivTable->count; i++)
01164 fprintf(fp," %s", equivTable->list[i].name);
01165 fprintf(fp, "\n");
01166
01167 fprintf(fp, "install arch : %s\n", current[ARCH]);
01168 fprintf(fp, "install os : %s\n", current[OS]);
01169
01170 fprintf(fp, "compatible archs :");
01171 for (mire = platpat, i = 0; i < nplatpat; i++)
01172 fprintf(fp, " %s", mire[i].pattern);
01173 fprintf(fp, "\n");
01174
01175 fprintf(fp, "compatible os's :");
01176 equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv;
01177 for (i = 0; i < equivTable->count; i++)
01178 fprintf(fp," %s", equivTable->list[i].name);
01179 fprintf(fp, "\n");
01180
01181 { const char * s = rpmExpand("%{?optflags}", NULL);
01182 fprintf(fp, "%-21s : %s\n", "optflags", ((s && *s) ? s : "(not set)"));
01183 s = _free(s);
01184
01185 #ifdef WITH_LUA
01186 fprintf(fp, "\nLUA MODULES:\n");
01187
01188 s = rpmExpand(rpmluaFiles, NULL);
01189
01190 fprintf(fp, "%-21s : %s\n", "luafiles", ((s && *s) ? s : "(not set)"));
01191 s = _free(s);
01192
01193 s = rpmExpand(rpmluaPath, NULL);
01194
01195 fprintf(fp, "%-21s : %s\n", "luapath", ((s && *s) ? s : "(not set)"));
01196 s = _free(s);
01197 #endif
01198
01199 fprintf(fp, "\nMACRO DEFINITIONS:\n");
01200
01201 s = rpmExpand(rpmMacrofiles, NULL);
01202
01203 fprintf(fp, "%-21s : %s\n", "macrofiles", ((s && *s) ? s : "(not set)"));
01204 s = _free(s);
01205 }
01206
01207 if (rpmIsVerbose()) {
01208 rpmPRCO PRCO = rpmdsNewPRCO(NULL);
01209 xx = rpmdsSysinfo(PRCO, NULL);
01210 ds = rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME);
01211 if (ds != NULL) {
01212 const char * fn = (_sysinfo_path ? _sysinfo_path : "/etc/rpm/sysinfo");
01213 fprintf(fp, _("Configured system provides (from %s):\n"), fn);
01214 ds = rpmdsInit(ds);
01215 while (rpmdsNext(ds) >= 0) {
01216 const char * DNEVR = rpmdsDNEVR(ds);
01217 if (DNEVR != NULL)
01218 fprintf(fp, " %s\n", DNEVR+2);
01219 }
01220 (void)rpmdsFree(ds);
01221 ds = NULL;
01222 fprintf(fp, "\n");
01223 }
01224 PRCO = rpmdsFreePRCO(PRCO);
01225 }
01226
01227 if (rpmIsVerbose()) {
01228 fprintf(fp, _("Features provided by rpmlib installer:\n"));
01229 xx = rpmdsRpmlib(&ds, NULL);
01230 ds = rpmdsInit(ds);
01231 while (rpmdsNext(ds) >= 0) {
01232 const char * DNEVR = rpmdsDNEVR(ds);
01233 if (DNEVR != NULL)
01234 fprintf(fp, " %s\n", DNEVR+2);
01235 }
01236 (void)rpmdsFree(ds);
01237 ds = NULL;
01238 fprintf(fp, "\n");
01239
01240 if(cpuinfoP == NULL)
01241 xx = rpmdsCpuinfo(&cpuinfoP, NULL);
01242 if (cpuinfoP != NULL) {
01243 #if defined(WITH_CPUINFO)
01244 const char * fn = "libcpuinfo";
01245 #else
01246 const char * fn = (_cpuinfo_path ? _cpuinfo_path : "/proc/cpuinfo");
01247 #endif
01248 fprintf(fp,
01249 _("Features provided by current cpuinfo (from %s):\n"), fn);
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
01259 fprintf(fp, "\n");
01260 }
01261 }
01262
01263 if (rpmIsDebug()) {
01264 xx = rpmdsGetconf(&ds, NULL);
01265 if (ds != NULL) {
01266 fprintf(fp,
01267 _("Features provided by current getconf:\n"));
01268 ds = rpmdsInit(ds);
01269 while (rpmdsNext(ds) >= 0) {
01270 const char * DNEVR = rpmdsDNEVR(ds);
01271 if (DNEVR != NULL)
01272 fprintf(fp, " %s\n", DNEVR+2);
01273 }
01274 (void)rpmdsFree(ds);
01275 ds = NULL;
01276 fprintf(fp, "\n");
01277 }
01278
01279 xx = rpmdsUname(&ds, NULL);
01280 if (ds != NULL) {
01281 fprintf(fp,
01282 _("Features provided by current uname:\n"));
01283 ds = rpmdsInit(ds);
01284 while (rpmdsNext(ds) >= 0) {
01285 const char * DNEVR = rpmdsDNEVR(ds);
01286 if (DNEVR != NULL)
01287 fprintf(fp, " %s\n", DNEVR+2);
01288 }
01289 (void)rpmdsFree(ds);
01290 ds = NULL;
01291 fprintf(fp, "\n");
01292 }
01293 }
01294
01295 rpmDumpMacroTable(NULL, fp);
01296
01297 return 0;
01298 }