00001
00002 #include "system.h"
00003
00004 #include <stdarg.h>
00005 #if defined(__linux__) && defined(__powerpc__)
00006 #include <setjmp.h>
00007 #endif
00008
00009 #include <ctype.h>
00010
00011 #if HAVE_SYS_SYSTEMCFG_H
00012 #include <sys/systemcfg.h>
00013 #else
00014 #define __power_pc() 0
00015 #endif
00016
00017 #include <rpmlib.h>
00018 #include <rpmmacro.h>
00019
00020 #include "misc.h"
00021 #include "debug.h"
00022
00023
00024 static const char *defrcfiles = LIBRPMRC_FILENAME ":" VENDORRPMRC_FILENAME ":/etc/rpmrc:~/.rpmrc";
00025
00026
00027 const char * macrofiles = MACROFILES;
00028
00029
00030 static const char * platform = "/etc/rpm/platform";
00031
00032 static const char ** platpat = NULL;
00033
00034 static int nplatpat = 0;
00035
00036 typedef const char * cptr_t;
00037
00038 typedef struct machCacheEntry_s {
00039 const char * name;
00040 int count;
00041 cptr_t * equivs;
00042 int visited;
00043 } * machCacheEntry;
00044
00045 typedef struct machCache_s {
00046 machCacheEntry cache;
00047 int size;
00048 } * machCache;
00049
00050 typedef struct machEquivInfo_s {
00051 const char * name;
00052 int score;
00053 } * machEquivInfo;
00054
00055 typedef struct machEquivTable_s {
00056 int count;
00057 machEquivInfo list;
00058 } * machEquivTable;
00059
00060 struct rpmvarValue {
00061 const char * value;
00062
00063 const char * arch;
00064 struct rpmvarValue * next;
00065 };
00066
00067 struct rpmOption {
00068 const char * name;
00069 int var;
00070 int archSpecific;
00071 int required;
00072 int macroize;
00073 int localize;
00074 struct rpmOptionValue * value;
00075 };
00076
00077 typedef struct defaultEntry_s {
00078 const char * name;
00079 const char * defName;
00080 } * defaultEntry;
00081
00082 typedef struct canonEntry_s {
00083 const char * name;
00084 const char * short_name;
00085 short num;
00086 } * canonEntry;
00087
00088
00089
00090
00091
00092 typedef struct tableType_s {
00093 const char * const key;
00094 const int hasCanon;
00095 const int hasTranslate;
00096 struct machEquivTable_s equiv;
00097 struct machCache_s cache;
00098 defaultEntry defaults;
00099 canonEntry canons;
00100 int defaultsLength;
00101 int canonsLength;
00102 } * tableType;
00103
00104
00105
00106 static struct tableType_s tables[RPM_MACHTABLE_COUNT] = {
00107 { "arch", 1, 0 },
00108 { "os", 1, 0 },
00109 { "buildarch", 0, 1 },
00110 { "buildos", 0, 1 }
00111 };
00112
00113
00114
00115
00116
00117 static struct rpmOption optionTable[] = {
00118 { "include", RPMVAR_INCLUDE, 0, 1, 0, 2 },
00119 { "macrofiles", RPMVAR_MACROFILES, 0, 0, 0, 1 },
00120 { "optflags", RPMVAR_OPTFLAGS, 1, 0, 1, 0 },
00121 { "provides", RPMVAR_PROVIDES, 0, 0, 0, 0 },
00122 };
00123
00124
00125
00126 static int optionTableSize = sizeof(optionTable) / sizeof(*optionTable);
00127
00128 #define OS 0
00129 #define ARCH 1
00130
00131
00132 static cptr_t current[2];
00133
00134
00135 static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH };
00136
00137
00138 static struct rpmvarValue values[RPMVAR_NUM];
00139
00140
00141 static int defaultsInitialized = 0;
00142
00143
00144 static int doReadRC( FD_t fd, const char * urlfn)
00145
00146 ;
00147
00148 static void rpmSetVarArch(int var, const char * val,
00149 const char * arch)
00150
00151 ;
00152
00153 static void rebuildCompatTables(int type, const char * name)
00154
00155 ;
00156
00157 static void rpmRebuildTargetVars( const char **target, const char ** canontarget)
00158
00159
00160 ;
00161
00162 static int optionCompare(const void * a, const void * b)
00163
00164 {
00165 return xstrcasecmp(((struct rpmOption *) a)->name,
00166 ((struct rpmOption *) b)->name);
00167 }
00168
00169 static machCacheEntry
00170 machCacheFindEntry(const machCache cache, const char * key)
00171
00172 {
00173 int i;
00174
00175 for (i = 0; i < cache->size; i++)
00176 if (!strcmp(cache->cache[i].name, key)) return cache->cache + i;
00177
00178 return NULL;
00179 }
00180
00181 static int machCompatCacheAdd(char * name, const char * fn, int linenum,
00182 machCache cache)
00183
00184
00185 {
00186 machCacheEntry entry = NULL;
00187 char * chptr;
00188 char * equivs;
00189 int delEntry = 0;
00190 int i;
00191
00192 while (*name && xisspace(*name)) name++;
00193
00194 chptr = name;
00195 while (*chptr && *chptr != ':') chptr++;
00196 if (!*chptr) {
00197 rpmError(RPMERR_RPMRC, _("missing second ':' at %s:%d\n"), fn, linenum);
00198 return 1;
00199 } else if (chptr == name) {
00200 rpmError(RPMERR_RPMRC, _("missing architecture name at %s:%d\n"), fn,
00201 linenum);
00202 return 1;
00203 }
00204
00205 while (*chptr == ':' || xisspace(*chptr)) chptr--;
00206 *(++chptr) = '\0';
00207 equivs = chptr + 1;
00208 while (*equivs && xisspace(*equivs)) equivs++;
00209 if (!*equivs) {
00210 delEntry = 1;
00211 }
00212
00213 if (cache->size) {
00214 entry = machCacheFindEntry(cache, name);
00215 if (entry) {
00216 for (i = 0; i < entry->count; i++)
00217 entry->equivs[i] = _free(entry->equivs[i]);
00218 entry->equivs = _free(entry->equivs);
00219 entry->count = 0;
00220 }
00221 }
00222
00223 if (!entry) {
00224 cache->cache = xrealloc(cache->cache,
00225 (cache->size + 1) * sizeof(*cache->cache));
00226 entry = cache->cache + cache->size++;
00227 entry->name = xstrdup(name);
00228 entry->count = 0;
00229 entry->visited = 0;
00230 }
00231
00232 if (delEntry) return 0;
00233
00234 while ((chptr = strtok(equivs, " ")) != NULL) {
00235 equivs = NULL;
00236 if (chptr[0] == '\0')
00237 continue;
00238 if (entry->count)
00239 entry->equivs = xrealloc(entry->equivs, sizeof(*entry->equivs)
00240 * (entry->count + 1));
00241 else
00242 entry->equivs = xmalloc(sizeof(*entry->equivs));
00243
00244 entry->equivs[entry->count] = xstrdup(chptr);
00245 entry->count++;
00246 }
00247
00248 return 0;
00249 }
00250
00251 static machEquivInfo
00252 machEquivSearch(const machEquivTable table, const char * name)
00253
00254 {
00255 int i;
00256
00257 for (i = 0; i < table->count; i++)
00258 if (!xstrcasecmp(table->list[i].name, name))
00259 return table->list + i;
00260
00261 return NULL;
00262 }
00263
00264 static void machAddEquiv(machEquivTable table, const char * name,
00265 int distance)
00266
00267 {
00268 machEquivInfo equiv;
00269
00270 equiv = machEquivSearch(table, name);
00271 if (!equiv) {
00272 if (table->count)
00273 table->list = xrealloc(table->list, (table->count + 1)
00274 * sizeof(*table->list));
00275 else
00276 table->list = xmalloc(sizeof(*table->list));
00277
00278 table->list[table->count].name = xstrdup(name);
00279 table->list[table->count++].score = distance;
00280 }
00281 }
00282
00283 static void machCacheEntryVisit(machCache cache,
00284 machEquivTable table, const char * name, int distance)
00285
00286 {
00287 machCacheEntry entry;
00288 int i;
00289
00290 entry = machCacheFindEntry(cache, name);
00291 if (!entry || entry->visited) return;
00292
00293 entry->visited = 1;
00294
00295 for (i = 0; i < entry->count; i++) {
00296 machAddEquiv(table, entry->equivs[i], distance);
00297 }
00298
00299 for (i = 0; i < entry->count; i++) {
00300 machCacheEntryVisit(cache, table, entry->equivs[i], distance + 1);
00301 }
00302 }
00303
00304 static void machFindEquivs(machCache cache, machEquivTable table,
00305 const char * key)
00306
00307 {
00308 int i;
00309
00310 for (i = 0; i < cache->size; i++)
00311 cache->cache[i].visited = 0;
00312
00313 while (table->count > 0) {
00314 --table->count;
00315 table->list[table->count].name = _free(table->list[table->count].name);
00316 }
00317 table->count = 0;
00318 table->list = _free(table->list);
00319
00320
00321
00322
00323
00324
00325
00326 machAddEquiv(table, key, 1);
00327 machCacheEntryVisit(cache, table, key, 2);
00328 return;
00329
00330 }
00331
00332 static int addCanon(canonEntry * table, int * tableLen, char * line,
00333 const char * fn, int lineNum)
00334
00335
00336 {
00337 canonEntry t;
00338 char *s, *s1;
00339 const char * tname;
00340 const char * tshort_name;
00341 int tnum;
00342
00343 (*tableLen) += 2;
00344
00345 *table = xrealloc(*table, sizeof(**table) * (*tableLen));
00346
00347
00348 t = & ((*table)[*tableLen - 2]);
00349
00350 tname = strtok(line, ": \t");
00351 tshort_name = strtok(NULL, " \t");
00352 s = strtok(NULL, " \t");
00353 if (! (tname && tshort_name && s)) {
00354 rpmError(RPMERR_RPMRC, _("Incomplete data line at %s:%d\n"),
00355 fn, lineNum);
00356 return RPMERR_RPMRC;
00357 }
00358 if (strtok(NULL, " \t")) {
00359 rpmError(RPMERR_RPMRC, _("Too many args in data line at %s:%d\n"),
00360 fn, lineNum);
00361 return RPMERR_RPMRC;
00362 }
00363
00364
00365 tnum = strtoul(s, &s1, 10);
00366 if ((*s1) || (s1 == s) || (tnum == ULONG_MAX)) {
00367 rpmError(RPMERR_RPMRC, _("Bad arch/os number: %s (%s:%d)\n"), s,
00368 fn, lineNum);
00369 return(RPMERR_RPMRC);
00370 }
00371
00372
00373 t[0].name = xstrdup(tname);
00374 t[0].short_name = (tshort_name ? xstrdup(tshort_name) : xstrdup(""));
00375 t[0].num = tnum;
00376
00377
00378
00379 t[1].name = (tshort_name ? xstrdup(tshort_name) : xstrdup(""));
00380 t[1].short_name = (tshort_name ? xstrdup(tshort_name) : xstrdup(""));
00381 t[1].num = tnum;
00382
00383 return 0;
00384 }
00385
00386 static int addDefault(defaultEntry * table, int * tableLen, char * line,
00387 const char * fn, int lineNum)
00388
00389
00390 {
00391 defaultEntry t;
00392
00393 (*tableLen)++;
00394
00395 *table = xrealloc(*table, sizeof(**table) * (*tableLen));
00396
00397
00398 t = & ((*table)[*tableLen - 1]);
00399
00400
00401 t->name = strtok(line, ": \t");
00402 t->defName = strtok(NULL, " \t");
00403 if (! (t->name && t->defName)) {
00404 rpmError(RPMERR_RPMRC, _("Incomplete default line at %s:%d\n"),
00405 fn, lineNum);
00406 return RPMERR_RPMRC;
00407 }
00408 if (strtok(NULL, " \t")) {
00409 rpmError(RPMERR_RPMRC, _("Too many args in default line at %s:%d\n"),
00410 fn, lineNum);
00411 return RPMERR_RPMRC;
00412 }
00413
00414 t->name = xstrdup(t->name);
00415 t->defName = (t->defName ? xstrdup(t->defName) : NULL);
00416
00417
00418 return 0;
00419 }
00420
00421 static canonEntry lookupInCanonTable(const char * name,
00422 const canonEntry table, int tableLen)
00423
00424 {
00425 while (tableLen) {
00426 tableLen--;
00427 if (strcmp(name, table[tableLen].name))
00428 continue;
00429
00430 return &(table[tableLen]);
00431
00432 }
00433
00434 return NULL;
00435 }
00436
00437 static
00438 const char * lookupInDefaultTable(const char * name,
00439 const defaultEntry table, int tableLen)
00440
00441 {
00442 while (tableLen) {
00443 tableLen--;
00444 if (table[tableLen].name && !strcmp(name, table[tableLen].name))
00445 return table[tableLen].defName;
00446 }
00447
00448 return name;
00449 }
00450
00451 static void setVarDefault(int var, const char * macroname, const char * val,
00452 const char * body)
00453
00454
00455 {
00456 if (var >= 0) {
00457 if (rpmGetVar(var)) return;
00458 rpmSetVar(var, val);
00459 }
00460 if (body == NULL)
00461 body = val;
00462 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
00463 }
00464
00465 static void setPathDefault(int var, const char * macroname, const char * subdir)
00466
00467
00468 {
00469
00470 if (var >= 0) {
00471 const char * topdir;
00472 char * fn;
00473
00474 if (rpmGetVar(var)) return;
00475
00476 topdir = rpmGetPath("%{_topdir}", NULL);
00477
00478 fn = alloca(strlen(topdir) + strlen(subdir) + 2);
00479 strcpy(fn, topdir);
00480 if (fn[strlen(topdir) - 1] != '/')
00481 strcat(fn, "/");
00482 strcat(fn, subdir);
00483
00484 rpmSetVar(var, fn);
00485 topdir = _free(topdir);
00486 }
00487
00488 if (macroname != NULL) {
00489 #define _TOPDIRMACRO "%{_topdir}/"
00490 char *body = alloca(sizeof(_TOPDIRMACRO) + strlen(subdir));
00491 strcpy(body, _TOPDIRMACRO);
00492 strcat(body, subdir);
00493 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
00494 #undef _TOPDIRMACRO
00495 }
00496 }
00497
00498
00499 static const char * prescriptenviron = "\n\
00500 RPM_SOURCE_DIR=\"%{_sourcedir}\"\n\
00501 RPM_BUILD_DIR=\"%{_builddir}\"\n\
00502 RPM_OPT_FLAGS=\"%{optflags}\"\n\
00503 RPM_ARCH=\"%{_arch}\"\n\
00504 RPM_OS=\"%{_os}\"\n\
00505 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\n\
00506 RPM_DOC_DIR=\"%{_docdir}\"\n\
00507 export RPM_DOC_DIR\n\
00508 RPM_PACKAGE_NAME=\"%{name}\"\n\
00509 RPM_PACKAGE_VERSION=\"%{version}\"\n\
00510 RPM_PACKAGE_RELEASE=\"%{release}\"\n\
00511 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\n\
00512 %{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\n\
00513 export RPM_BUILD_ROOT\n}\
00514 ";
00515
00516 static void setDefaults(void)
00517
00518
00519 {
00520
00521 addMacro(NULL, "_usr", NULL, "/usr", RMIL_DEFAULT);
00522 addMacro(NULL, "_var", NULL, "/var", RMIL_DEFAULT);
00523
00524 addMacro(NULL, "_preScriptEnvironment",NULL, prescriptenviron,RMIL_DEFAULT);
00525
00526 setVarDefault(-1, "_topdir",
00527 "/usr/src/redhat", "%{_usr}/src/redhat");
00528 setVarDefault(-1, "_tmppath",
00529 "/var/tmp", "%{_var}/tmp");
00530 setVarDefault(-1, "_dbpath",
00531 "/var/lib/rpm", "%{_var}/lib/rpm");
00532 setVarDefault(-1, "_defaultdocdir",
00533 "/usr/doc", "%{_usr}/doc");
00534
00535 setVarDefault(-1, "_rpmfilename",
00536 "%%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm",NULL);
00537
00538 setVarDefault(RPMVAR_OPTFLAGS, "optflags",
00539 "-O2", NULL);
00540 setVarDefault(-1, "sigtype",
00541 "none", NULL);
00542 setVarDefault(-1, "_buildshell",
00543 "/bin/sh", NULL);
00544
00545 setPathDefault(-1, "_builddir", "BUILD");
00546 setPathDefault(-1, "_rpmdir", "RPMS");
00547 setPathDefault(-1, "_srcrpmdir", "SRPMS");
00548 setPathDefault(-1, "_sourcedir", "SOURCES");
00549 setPathDefault(-1, "_specdir", "SPECS");
00550
00551 }
00552
00553
00554 static int doReadRC( FD_t fd, const char * urlfn)
00555
00556
00557 {
00558 const char *s;
00559 char *se, *next;
00560 int linenum = 0;
00561 struct rpmOption searchOption, * option;
00562 int rc;
00563
00564
00565 { off_t size = fdSize(fd);
00566 size_t nb = (size >= 0 ? size : (8*BUFSIZ - 2));
00567 if (nb == 0) {
00568 (void) Fclose(fd);
00569 return 0;
00570 }
00571 next = alloca(nb + 2);
00572 next[0] = '\0';
00573 rc = Fread(next, sizeof(*next), nb, fd);
00574 if (Ferror(fd) || (size > 0 && rc != nb)) {
00575 rpmError(RPMERR_RPMRC, _("Failed to read %s: %s.\n"), urlfn,
00576 Fstrerror(fd));
00577 rc = 1;
00578 } else
00579 rc = 0;
00580 (void) Fclose(fd);
00581 if (rc) return rc;
00582 next[nb] = '\n';
00583 next[nb + 1] = '\0';
00584 }
00585
00586
00587 while (*next != '\0') {
00588 linenum++;
00589
00590 s = se = next;
00591
00592
00593 while (*se && *se != '\n') se++;
00594 if (*se != '\0') *se++ = '\0';
00595 next = se;
00596
00597
00598 while (*s && xisspace(*s)) s++;
00599
00600
00601 if (*s == '#' || *s == '\0') continue;
00602
00603
00604 se = (char *)s;
00605 while (*se && !xisspace(*se) && *se != ':') se++;
00606
00607 if (xisspace(*se)) {
00608 *se++ = '\0';
00609 while (*se && xisspace(*se) && *se != ':') se++;
00610 }
00611
00612 if (*se != ':') {
00613 rpmError(RPMERR_RPMRC, _("missing ':' (found 0x%02x) at %s:%d\n"),
00614 (unsigned)(0xff & *se), urlfn, linenum);
00615 return 1;
00616 }
00617 *se++ = '\0';
00618 while (*se && xisspace(*se)) se++;
00619
00620
00621 searchOption.name = s;
00622 option = bsearch(&searchOption, optionTable, optionTableSize,
00623 sizeof(optionTable[0]), optionCompare);
00624
00625 if (option) {
00626 const char *arch, *val, *fn;
00627
00628 arch = val = fn = NULL;
00629 if (*se == '\0') {
00630 rpmError(RPMERR_RPMRC, _("missing argument for %s at %s:%d\n"),
00631 option->name, urlfn, linenum);
00632 return 1;
00633 }
00634
00635 switch (option->var) {
00636 case RPMVAR_INCLUDE:
00637 { FD_t fdinc;
00638
00639 s = se;
00640 while (*se && !xisspace(*se)) se++;
00641 if (*se != '\0') *se++ = '\0';
00642
00643 rpmRebuildTargetVars(NULL, NULL);
00644
00645 fn = rpmGetPath(s, NULL);
00646 if (fn == NULL || *fn == '\0') {
00647 rpmError(RPMERR_RPMRC, _("%s expansion failed at %s:%d \"%s\"\n"),
00648 option->name, urlfn, linenum, s);
00649 fn = _free(fn);
00650 return 1;
00651
00652 }
00653
00654 fdinc = Fopen(fn, "r.fpio");
00655 if (fdinc == NULL || Ferror(fdinc)) {
00656 rpmError(RPMERR_RPMRC, _("cannot open %s at %s:%d: %s\n"),
00657 fn, urlfn, linenum, Fstrerror(fdinc));
00658 rc = 1;
00659 } else {
00660 rc = doReadRC(fdinc, fn);
00661 }
00662 fn = _free(fn);
00663 if (rc) return rc;
00664 continue;
00665 } break;
00666 case RPMVAR_MACROFILES:
00667 fn = rpmGetPath(se, NULL);
00668 if (fn == NULL || *fn == '\0') {
00669 rpmError(RPMERR_RPMRC, _("%s expansion failed at %s:%d \"%s\"\n"),
00670 option->name, urlfn, linenum, fn);
00671 fn = _free(fn);
00672 return 1;
00673 }
00674 se = (char *)fn;
00675 break;
00676 case RPMVAR_PROVIDES:
00677 { char *t;
00678 s = rpmGetVar(RPMVAR_PROVIDES);
00679 if (s == NULL) s = "";
00680 fn = t = xmalloc(strlen(s) + strlen(se) + 2);
00681 while (*s != '\0') *t++ = *s++;
00682 *t++ = ' ';
00683 while (*se != '\0') *t++ = *se++;
00684 *t++ = '\0';
00685 se = (char *)fn;
00686 } break;
00687 default:
00688 break;
00689 }
00690
00691 if (option->archSpecific) {
00692 arch = se;
00693 while (*se && !xisspace(*se)) se++;
00694 if (*se == '\0') {
00695 rpmError(RPMERR_RPMRC,
00696 _("missing architecture for %s at %s:%d\n"),
00697 option->name, urlfn, linenum);
00698 return 1;
00699 }
00700 *se++ = '\0';
00701 while (*se && xisspace(*se)) se++;
00702 if (*se == '\0') {
00703 rpmError(RPMERR_RPMRC,
00704 _("missing argument for %s at %s:%d\n"),
00705 option->name, urlfn, linenum);
00706 return 1;
00707 }
00708 }
00709
00710 val = se;
00711
00712
00713 if (option->macroize &&
00714 (arch == NULL || !strcmp(arch, current[ARCH]))) {
00715 char *n, *name;
00716 n = name = xmalloc(strlen(option->name)+2);
00717 if (option->localize)
00718 *n++ = '_';
00719 strcpy(n, option->name);
00720 addMacro(NULL, name, NULL, val, RMIL_RPMRC);
00721 free(name);
00722 }
00723 rpmSetVarArch(option->var, val, arch);
00724 fn = _free(fn);
00725
00726 } else {
00727 int gotit;
00728 int i;
00729
00730 gotit = 0;
00731
00732 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
00733 if (!strncmp(tables[i].key, s, strlen(tables[i].key)))
00734 break;
00735 }
00736
00737 if (i < RPM_MACHTABLE_COUNT) {
00738 const char *rest = s + strlen(tables[i].key);
00739 if (*rest == '_') rest++;
00740
00741 if (!strcmp(rest, "compat")) {
00742 if (machCompatCacheAdd(se, urlfn, linenum,
00743 &tables[i].cache))
00744 return 1;
00745 gotit = 1;
00746 } else if (tables[i].hasTranslate &&
00747 !strcmp(rest, "translate")) {
00748 if (addDefault(&tables[i].defaults,
00749 &tables[i].defaultsLength,
00750 se, urlfn, linenum))
00751 return 1;
00752 gotit = 1;
00753 } else if (tables[i].hasCanon &&
00754 !strcmp(rest, "canon")) {
00755 if (addCanon(&tables[i].canons, &tables[i].canonsLength,
00756 se, urlfn, linenum))
00757 return 1;
00758 gotit = 1;
00759 }
00760 }
00761
00762 if (!gotit) {
00763 rpmError(RPMERR_RPMRC, _("bad option '%s' at %s:%d\n"),
00764 s, urlfn, linenum);
00765 }
00766 }
00767 }
00768
00769
00770 return 0;
00771 }
00772
00773
00774
00777
00778 static int rpmPlatform(const char * platform)
00779
00780
00781
00782
00783 {
00784 char *cpu = NULL, *vendor = NULL, *os = NULL, *gnu = NULL;
00785 char * b = NULL;
00786 ssize_t blen = 0;
00787 int init_platform = 0;
00788 char * p, * pe;
00789 int rc;
00790
00791 rc = rpmioSlurp(platform, &b, &blen);
00792
00793 if (rc || b == NULL || blen <= 0) {
00794 rc = -1;
00795 goto exit;
00796 }
00797
00798 p = b;
00799 for (pe = p; p && *p; p = pe) {
00800 pe = strchr(p, '\n');
00801 if (pe)
00802 *pe++ = '\0';
00803
00804 while (*p && isspace(*p))
00805 p++;
00806 if (*p == '\0' || *p == '#')
00807 continue;
00808
00809 if (init_platform) {
00810 char * t = p + strlen(p);
00811
00812 while (--t > p && isspace(*t))
00813 *t = '\0';
00814 if (t > p) {
00815 platpat = xrealloc(platpat, (nplatpat + 2) * sizeof(*platpat));
00816
00817 platpat[nplatpat] = xstrdup(p);
00818 nplatpat++;
00819 platpat[nplatpat] = NULL;
00820
00821 }
00822 continue;
00823 }
00824
00825 cpu = p;
00826 vendor = "unknown";
00827 os = "unknown";
00828 gnu = NULL;
00829 while (*p && !(*p == '-' || isspace(*p)))
00830 p++;
00831 if (*p != '\0') *p++ = '\0';
00832
00833 vendor = p;
00834 while (*p && !(*p == '-' || isspace(*p)))
00835 p++;
00836
00837 if (*p != '-') {
00838 if (*p != '\0') *p++ = '\0';
00839 os = vendor;
00840 vendor = "unknown";
00841 } else {
00842 if (*p != '\0') *p++ = '\0';
00843
00844 os = p;
00845 while (*p && !(*p == '-' || isspace(*p)))
00846 p++;
00847 if (*p == '-') {
00848 *p++ = '\0';
00849
00850 gnu = p;
00851 while (*p && !(*p == '-' || isspace(*p)))
00852 p++;
00853 }
00854 if (*p != '\0') *p++ = '\0';
00855 }
00856
00857
00858 addMacro(NULL, "_host_cpu", NULL, cpu, -1);
00859 addMacro(NULL, "_host_vendor", NULL, vendor, -1);
00860 addMacro(NULL, "_host_os", NULL, os, -1);
00861
00862 platpat = xrealloc(platpat, (nplatpat + 2) * sizeof(*platpat));
00863
00864 platpat[nplatpat] = rpmExpand("%{_host_cpu}-%{_host_vendor}-%{_host_os}", (gnu && *gnu ? "-" : NULL), gnu, NULL);
00865 nplatpat++;
00866 platpat[nplatpat] = NULL;
00867
00868
00869 init_platform++;
00870 }
00871 rc = (init_platform ? 0 : -1);
00872
00873 exit:
00874
00875 b = _free(b);
00876
00877 return rc;
00878 }
00879
00880
00881
00882 # if defined(__linux__) && defined(__i386__)
00883 #include <setjmp.h>
00884 #include <signal.h>
00885
00886
00887
00888
00889 static inline void cpuid(unsigned int op, int *eax, int *ebx, int *ecx, int *edx)
00890
00891 {
00892 #ifdef __LCLINT__
00893 *eax = *ebx = *ecx = *edx = 0;
00894 #endif
00895 #ifdef PIC
00896 __asm__("pushl %%ebx; cpuid; movl %%ebx,%1; popl %%ebx"
00897 : "=a"(*eax), "=g"(*ebx), "=&c"(*ecx), "=&d"(*edx)
00898 : "a" (op));
00899 #else
00900 __asm__("cpuid"
00901 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
00902 : "a" (op));
00903 #endif
00904
00905 }
00906
00907
00908
00909
00910 static inline unsigned int cpuid_eax(unsigned int op)
00911
00912 {
00913 unsigned int val;
00914
00915 #ifdef PIC
00916 __asm__("pushl %%ebx; cpuid; popl %%ebx"
00917 : "=a" (val) : "a" (op) : "ecx", "edx");
00918 #else
00919 __asm__("cpuid"
00920 : "=a" (val) : "a" (op) : "ebx", "ecx", "edx");
00921 #endif
00922 return val;
00923 }
00924
00925 static inline unsigned int cpuid_ebx(unsigned int op)
00926
00927 {
00928 unsigned int tmp, val;
00929
00930 #ifdef PIC
00931 __asm__("pushl %%ebx; cpuid; movl %%ebx,%1; popl %%ebx"
00932 : "=a" (tmp), "=g" (val) : "a" (op) : "ecx", "edx");
00933 #else
00934 __asm__("cpuid"
00935 : "=a" (tmp), "=b" (val) : "a" (op) : "ecx", "edx");
00936 #endif
00937 return val;
00938 }
00939
00940 static inline unsigned int cpuid_ecx(unsigned int op)
00941
00942 {
00943 unsigned int tmp, val;
00944 #ifdef PIC
00945 __asm__("pushl %%ebx; cpuid; popl %%ebx"
00946 : "=a" (tmp), "=c" (val) : "a" (op) : "edx");
00947 #else
00948 __asm__("cpuid"
00949 : "=a" (tmp), "=c" (val) : "a" (op) : "ebx", "edx");
00950 #endif
00951 return val;
00952
00953 }
00954
00955 static inline unsigned int cpuid_edx(unsigned int op)
00956
00957 {
00958 unsigned int tmp, val;
00959 #ifdef PIC
00960 __asm__("pushl %%ebx; cpuid; popl %%ebx"
00961 : "=a" (tmp), "=d" (val) : "a" (op) : "ecx");
00962 #else
00963 __asm__("cpuid"
00964 : "=a" (tmp), "=d" (val) : "a" (op) : "ebx", "ecx");
00965 #endif
00966 return val;
00967
00968 }
00969
00970
00971 static sigjmp_buf jenv;
00972
00973 static inline void model3(int _unused)
00974
00975
00976 {
00977 siglongjmp(jenv, 1);
00978 }
00979
00980 static inline int RPMClass(void)
00981
00982
00983 {
00984 int cpu;
00985 unsigned int tfms, junk, cap, capamd;
00986
00987 signal(SIGILL, model3);
00988
00989 if (sigsetjmp(jenv, 1))
00990 return 3;
00991
00992 if (cpuid_eax(0x000000000)==0)
00993 return 4;
00994
00995 cpuid(0x00000001, &tfms, &junk, &junk, &cap);
00996 cpuid(0x80000001, &junk, &junk, &junk, &capamd);
00997
00998 cpu = (tfms>>8)&15;
00999
01000 if (cpu < 6)
01001 return cpu;
01002
01003 if (cap & (1<<15)) {
01004
01005 if (capamd & (1<<30))
01006 return 7;
01007 return 6;
01008 }
01009
01010 return 5;
01011 }
01012
01013
01014 static int is_athlon(void)
01015
01016 {
01017 unsigned int eax, ebx, ecx, edx;
01018 char vendor[16];
01019 int i;
01020
01021 cpuid (0, &eax, &ebx, &ecx, &edx);
01022
01023
01024
01025 memset(vendor, 0, sizeof(vendor));
01026
01027 for (i=0; i<4; i++)
01028 vendor[i] = (unsigned char) (ebx >>(8*i));
01029 for (i=0; i<4; i++)
01030 vendor[4+i] = (unsigned char) (edx >>(8*i));
01031 for (i=0; i<4; i++)
01032 vendor[8+i] = (unsigned char) (ecx >>(8*i));
01033
01034 if (strncmp(vendor, "AuthenticAMD", 12) != 0)
01035 return 0;
01036
01037 return 1;
01038 }
01039
01040 #endif
01041
01042 #if defined(__linux__) && defined(__powerpc__)
01043 static jmp_buf mfspr_jmpbuf;
01044
01045 static void mfspr_ill(int notused)
01046 {
01047 longjmp(mfspr_jmpbuf, -1);
01048 }
01049 #endif
01050
01053 static void defaultMachine( const char ** arch,
01054 const char ** os)
01055
01056
01057 {
01058 static struct utsname un;
01059 static int gotDefaults = 0;
01060 char * chptr;
01061 canonEntry canon;
01062 int rc;
01063
01064 while (!gotDefaults) {
01065 if (!rpmPlatform(platform)) {
01066 const char * s;
01067 s = rpmExpand("%{_host_cpu}", NULL);
01068 if (s) {
01069 strncpy(un.machine, s, sizeof(un.machine));
01070 un.machine[sizeof(un.machine)-1] = '\0';
01071 s = _free(s);
01072 }
01073 s = rpmExpand("%{_host_os}", NULL);
01074 if (s) {
01075 strncpy(un.sysname, s, sizeof(un.sysname));
01076 un.sysname[sizeof(un.sysname)-1] = '\0';
01077 s = _free(s);
01078 }
01079 gotDefaults = 1;
01080 break;
01081 }
01082 rc = uname(&un);
01083 if (rc < 0) return;
01084
01085 #if !defined(__linux__)
01086 #ifdef SNI
01087
01088
01089
01090 strncpy(un.sysname, "SINIX", sizeof(un.sysname));
01091 #endif
01092
01093 if (!strcmp(un.sysname, "AIX")) {
01094 strcpy(un.machine, __power_pc() ? "ppc" : "rs6000");
01095 sprintf(un.sysname,"aix%s.%s", un.version, un.release);
01096 }
01097 else if (!strcmp(un.sysname, "SunOS")) {
01098 if (!strncmp(un.release,"4", 1)) {
01099 int fd;
01100 for (fd = 0;
01101 (un.release[fd] != 0 && (fd < sizeof(un.release)));
01102 fd++) {
01103 if (!xisdigit(un.release[fd]) && (un.release[fd] != '.')) {
01104 un.release[fd] = 0;
01105 break;
01106 }
01107 }
01108 sprintf(un.sysname,"sunos%s",un.release);
01109 }
01110
01111 else
01112 sprintf(un.sysname, "solaris%1d%s", atoi(un.release)-3,
01113 un.release+1+(atoi(un.release)/10));
01114
01115
01116
01117
01118 if (!strcmp(un.machine, "i86pc"))
01119 sprintf(un.machine, "i386");
01120 }
01121 else if (!strcmp(un.sysname, "HP-UX"))
01122
01123 sprintf(un.sysname, "hpux%s", strpbrk(un.release, "123456789"));
01124 else if (!strcmp(un.sysname, "OSF1"))
01125
01126 sprintf(un.sysname, "osf%s", strpbrk(un.release, "123456789"));
01127 else if (!strncmp(un.sysname, "IP", 2))
01128 un.sysname[2] = '\0';
01129 else if (!strncmp(un.sysname, "SINIX", 5)) {
01130 sprintf(un.sysname, "sinix%s",un.release);
01131 if (!strncmp(un.machine, "RM", 2))
01132 sprintf(un.machine, "mips");
01133 }
01134 else if ((!strncmp(un.machine, "34", 2) ||
01135 !strncmp(un.machine, "33", 2)) && \
01136 !strncmp(un.release, "4.0", 3))
01137 {
01138
01139 char * prelid = NULL;
01140 FD_t fd = Fopen("/etc/.relid", "r.fdio");
01141 int gotit = 0;
01142
01143 if (fd != NULL && !Ferror(fd)) {
01144 chptr = xcalloc(1, 256);
01145 { int irelid = Fread(chptr, sizeof(*chptr), 256, fd);
01146 (void) Fclose(fd);
01147
01148 if (irelid > 0) {
01149 if ((prelid = strstr(chptr, "RELEASE "))){
01150 prelid += strlen("RELEASE ")+1;
01151 sprintf(un.sysname,"ncr-sysv4.%.*s",1,prelid);
01152 gotit = 1;
01153 }
01154 }
01155 }
01156 chptr = _free (chptr);
01157 }
01158
01159 if (!gotit)
01160 strcpy(un.sysname,"ncr-sysv4");
01161
01162 strcpy(un.machine,"i486");
01163 }
01164
01165 #endif
01166
01167
01168 for (chptr = un.machine; *chptr != '\0'; chptr++)
01169 if (*chptr == '/') *chptr = '-';
01170
01171 # if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
01172
01173 strcpy(un.machine, "mipsel");
01174 # elif defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB)
01175
01176 strcpy(un.machine, "mips");
01177 # endif
01178
01179 # if defined(__hpux) && defined(_SC_CPU_VERSION)
01180 {
01181 # if !defined(CPU_PA_RISC1_2)
01182 # define CPU_PA_RISC1_2 0x211
01183 # endif
01184 # if !defined(CPU_PA_RISC2_0)
01185 # define CPU_PA_RISC2_0 0x214
01186 # endif
01187 int cpu_version = sysconf(_SC_CPU_VERSION);
01188
01189 # if defined(CPU_HP_MC68020)
01190 if (cpu_version == CPU_HP_MC68020)
01191 strcpy(un.machine, "m68k");
01192 # endif
01193 # if defined(CPU_HP_MC68030)
01194 if (cpu_version == CPU_HP_MC68030)
01195 strcpy(un.machine, "m68k");
01196 # endif
01197 # if defined(CPU_HP_MC68040)
01198 if (cpu_version == CPU_HP_MC68040)
01199 strcpy(un.machine, "m68k");
01200 # endif
01201
01202 # if defined(CPU_PA_RISC1_0)
01203 if (cpu_version == CPU_PA_RISC1_0)
01204 strcpy(un.machine, "hppa1.0");
01205 # endif
01206 # if defined(CPU_PA_RISC1_1)
01207 if (cpu_version == CPU_PA_RISC1_1)
01208 strcpy(un.machine, "hppa1.1");
01209 # endif
01210 # if defined(CPU_PA_RISC1_2)
01211 if (cpu_version == CPU_PA_RISC1_2)
01212 strcpy(un.machine, "hppa1.2");
01213 # endif
01214 # if defined(CPU_PA_RISC2_0)
01215 if (cpu_version == CPU_PA_RISC2_0)
01216 strcpy(un.machine, "hppa2.0");
01217 # endif
01218 }
01219 # endif
01220
01221 # if defined(__linux__) && defined(__sparc__)
01222 if (!strcmp(un.machine, "sparc")) {
01223 #define PERS_LINUX 0x00000000
01224 #define PERS_LINUX_32BIT 0x00800000
01225 #define PERS_LINUX32 0x00000008
01226
01227 extern int personality(unsigned long);
01228 int oldpers;
01229
01230 oldpers = personality(PERS_LINUX_32BIT);
01231 if (oldpers != -1) {
01232 if (personality(PERS_LINUX) != -1) {
01233 uname(&un);
01234 if (! strcmp(un.machine, "sparc64")) {
01235 strcpy(un.machine, "sparcv9");
01236 oldpers = PERS_LINUX32;
01237 }
01238 }
01239 personality(oldpers);
01240 }
01241 }
01242 # endif
01243
01244 # if defined(__GNUC__) && defined(__alpha__)
01245 {
01246 unsigned long amask, implver;
01247 register long v0 __asm__("$0") = -1;
01248 __asm__ (".long 0x47e00c20" : "=r"(v0) : "0"(v0));
01249 amask = ~v0;
01250 __asm__ (".long 0x47e03d80" : "=r"(v0));
01251 implver = v0;
01252 switch (implver) {
01253 case 1:
01254 switch (amask) {
01255 case 0: strcpy(un.machine, "alphaev5"); break;
01256 case 1: strcpy(un.machine, "alphaev56"); break;
01257 case 0x101: strcpy(un.machine, "alphapca56"); break;
01258 }
01259 break;
01260 case 2:
01261 switch (amask) {
01262 case 0x303: strcpy(un.machine, "alphaev6"); break;
01263 case 0x307: strcpy(un.machine, "alphaev67"); break;
01264 }
01265 break;
01266 }
01267 }
01268 # endif
01269
01270 # if defined(__linux__) && defined(__i386__)
01271 {
01272 char class = (char) (RPMClass() | '0');
01273
01274 if ((class == '6' && is_athlon()) || class == '7')
01275 strcpy(un.machine, "athlon");
01276 else if (strchr("3456", un.machine[1]) && un.machine[1] != class)
01277 un.machine[1] = class;
01278 }
01279 # endif
01280
01281
01282 canon = lookupInCanonTable(un.machine,
01283 tables[RPM_MACHTABLE_INSTARCH].canons,
01284 tables[RPM_MACHTABLE_INSTARCH].canonsLength);
01285 if (canon)
01286 strcpy(un.machine, canon->short_name);
01287
01288 canon = lookupInCanonTable(un.sysname,
01289 tables[RPM_MACHTABLE_INSTOS].canons,
01290 tables[RPM_MACHTABLE_INSTOS].canonsLength);
01291 if (canon)
01292 strcpy(un.sysname, canon->short_name);
01293 gotDefaults = 1;
01294 break;
01295 }
01296
01297 if (arch) *arch = un.machine;
01298 if (os) *os = un.sysname;
01299 }
01300
01301 static
01302 const char * rpmGetVarArch(int var, const char * arch)
01303
01304 {
01305 const struct rpmvarValue * next;
01306
01307 if (arch == NULL) arch = current[ARCH];
01308
01309 if (arch) {
01310 next = &values[var];
01311 while (next) {
01312 if (next->arch && !strcmp(next->arch, arch)) return next->value;
01313 next = next->next;
01314 }
01315 }
01316
01317 next = values + var;
01318 while (next && next->arch) next = next->next;
01319
01320 return next ? next->value : NULL;
01321 }
01322
01323 const char *rpmGetVar(int var)
01324 {
01325 return rpmGetVarArch(var, NULL);
01326 }
01327
01328
01329 static void freeRpmVar( struct rpmvarValue * orig)
01330
01331 {
01332 struct rpmvarValue * next, * var = orig;
01333
01334 while (var) {
01335 next = var->next;
01336 var->arch = _free(var->arch);
01337 var->value = _free(var->value);
01338
01339
01340 if (var != orig) var = _free(var);
01341
01342 var = next;
01343 }
01344 }
01345
01346 void rpmSetVar(int var, const char * val)
01347
01348
01349 {
01350
01351 freeRpmVar(&values[var]);
01352
01353 values[var].value = (val ? xstrdup(val) : NULL);
01354 }
01355
01356 static void rpmSetVarArch(int var, const char * val, const char * arch)
01357 {
01358 struct rpmvarValue * next = values + var;
01359
01360 if (next->value) {
01361 if (arch) {
01362 while (next->next) {
01363 if (next->arch && !strcmp(next->arch, arch)) break;
01364 next = next->next;
01365 }
01366 } else {
01367 while (next->next) {
01368 if (!next->arch) break;
01369 next = next->next;
01370 }
01371 }
01372
01373
01374 if (next->arch && arch && !strcmp(next->arch, arch)) {
01375
01376 next->value = _free(next->value);
01377 next->arch = _free(next->arch);
01378 } else if (next->arch || arch) {
01379 next->next = xmalloc(sizeof(*next->next));
01380 next = next->next;
01381 next->value = NULL;
01382 next->arch = NULL;
01383 next->next = NULL;
01384 }
01385 }
01386
01387 next->value = xstrdup(val);
01388 next->arch = (arch ? xstrdup(arch) : NULL);
01389 }
01390
01391 void rpmSetTables(int archTable, int osTable)
01392
01393
01394 {
01395 const char * arch, * os;
01396
01397 defaultMachine(&arch, &os);
01398
01399 if (currTables[ARCH] != archTable) {
01400 currTables[ARCH] = archTable;
01401 rebuildCompatTables(ARCH, arch);
01402 }
01403
01404 if (currTables[OS] != osTable) {
01405 currTables[OS] = osTable;
01406 rebuildCompatTables(OS, os);
01407 }
01408 }
01409
01410 int rpmMachineScore(int type, const char * name)
01411 {
01412 machEquivInfo info = machEquivSearch(&tables[type].equiv, name);
01413 return (info != NULL ? info->score : 0);
01414 }
01415
01416 void rpmGetMachine(const char ** arch, const char ** os)
01417 {
01418 if (arch)
01419 *arch = current[ARCH];
01420
01421 if (os)
01422 *os = current[OS];
01423 }
01424
01425 void rpmSetMachine(const char * arch, const char * os)
01426
01427
01428 {
01429 const char * host_cpu, * host_os;
01430
01431 defaultMachine(&host_cpu, &host_os);
01432
01433 if (arch == NULL) {
01434 arch = host_cpu;
01435 if (tables[currTables[ARCH]].hasTranslate)
01436 arch = lookupInDefaultTable(arch,
01437 tables[currTables[ARCH]].defaults,
01438 tables[currTables[ARCH]].defaultsLength);
01439 }
01440 if (arch == NULL) return;
01441
01442 if (os == NULL) {
01443 os = host_os;
01444 if (tables[currTables[OS]].hasTranslate)
01445 os = lookupInDefaultTable(os,
01446 tables[currTables[OS]].defaults,
01447 tables[currTables[OS]].defaultsLength);
01448 }
01449 if (os == NULL) return;
01450
01451 if (!current[ARCH] || strcmp(arch, current[ARCH])) {
01452 current[ARCH] = _free(current[ARCH]);
01453 current[ARCH] = xstrdup(arch);
01454 rebuildCompatTables(ARCH, host_cpu);
01455 }
01456
01457 if (!current[OS] || strcmp(os, current[OS])) {
01458 char * t = xstrdup(os);
01459 current[OS] = _free(current[OS]);
01460
01461
01462
01463
01464
01465
01466
01467
01468 if (!strcmp(t, "linux"))
01469 *t = 'L';
01470 current[OS] = t;
01471
01472 rebuildCompatTables(OS, host_os);
01473 }
01474 }
01475
01476 static void rebuildCompatTables(int type, const char * name)
01477
01478 {
01479 machFindEquivs(&tables[currTables[type]].cache,
01480 &tables[currTables[type]].equiv,
01481 name);
01482 }
01483
01484 static void getMachineInfo(int type, const char ** name,
01485 int * num)
01486
01487 {
01488 canonEntry canon;
01489 int which = currTables[type];
01490
01491
01492 if (which >= 2) which -= 2;
01493
01494 canon = lookupInCanonTable(current[type],
01495 tables[which].canons,
01496 tables[which].canonsLength);
01497
01498 if (canon) {
01499 if (num) *num = canon->num;
01500 if (name) *name = canon->short_name;
01501 } else {
01502 if (num) *num = 255;
01503 if (name) *name = current[type];
01504
01505 if (tables[currTables[type]].hasCanon) {
01506 rpmMessage(RPMMESS_WARNING, _("Unknown system: %s\n"), current[type]);
01507 rpmMessage(RPMMESS_WARNING, _("Please contact rpm-list@redhat.com\n"));
01508 }
01509 }
01510 }
01511
01512 void rpmGetArchInfo(const char ** name, int * num)
01513 {
01514 getMachineInfo(ARCH, name, num);
01515 }
01516
01517 void rpmGetOsInfo(const char ** name, int * num)
01518 {
01519 getMachineInfo(OS, name, num);
01520 }
01521
01522 static void rpmRebuildTargetVars(const char ** target, const char ** canontarget)
01523 {
01524
01525 char *ca = NULL, *co = NULL, *ct = NULL;
01526 int x;
01527
01528
01529
01530 rpmSetMachine(NULL, NULL);
01531 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS);
01532 rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
01533
01534
01535 if (target && *target) {
01536 char *c;
01537
01538 ca = xstrdup(*target);
01539 if ((c = strchr(ca, '-')) != NULL) {
01540 *c++ = '\0';
01541
01542 if ((co = strrchr(c, '-')) == NULL) {
01543 co = c;
01544 } else {
01545 if (!xstrcasecmp(co, "-gnu"))
01546 *co = '\0';
01547 if ((co = strrchr(c, '-')) == NULL)
01548 co = c;
01549 else
01550 co++;
01551 }
01552 if (co != NULL) co = xstrdup(co);
01553 }
01554 } else {
01555 const char *a = NULL;
01556 const char *o = NULL;
01557
01558 rpmGetArchInfo(&a, NULL);
01559 ca = (a) ? xstrdup(a) : NULL;
01560 rpmGetOsInfo(&o, NULL);
01561 co = (o) ? xstrdup(o) : NULL;
01562 }
01563
01564
01565
01566 if (ca == NULL) {
01567 const char *a = NULL;
01568 defaultMachine(&a, NULL);
01569 ca = (a) ? xstrdup(a) : NULL;
01570 }
01571 for (x = 0; ca[x] != '\0'; x++)
01572 ca[x] = xtolower(ca[x]);
01573
01574 if (co == NULL) {
01575 const char *o = NULL;
01576 defaultMachine(NULL, &o);
01577 co = (o) ? xstrdup(o) : NULL;
01578 }
01579 for (x = 0; co[x] != '\0'; x++)
01580 co[x] = xtolower(co[x]);
01581
01582
01583 if (ct == NULL) {
01584 ct = xmalloc(strlen(ca) + sizeof("-") + strlen(co));
01585 sprintf(ct, "%s-%s", ca, co);
01586 }
01587
01588
01589
01590
01591
01592 delMacro(NULL, "_target");
01593 addMacro(NULL, "_target", NULL, ct, RMIL_RPMRC);
01594 delMacro(NULL, "_target_cpu");
01595 addMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC);
01596 delMacro(NULL, "_target_os");
01597 addMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC);
01598
01599
01600
01601 { const char *optflags = rpmGetVarArch(RPMVAR_OPTFLAGS, ca);
01602 if (optflags != NULL) {
01603 delMacro(NULL, "optflags");
01604 addMacro(NULL, "optflags", NULL, optflags, RMIL_RPMRC);
01605 }
01606 }
01607
01608
01609 if (canontarget)
01610 *canontarget = ct;
01611 else
01612 ct = _free(ct);
01613
01614 ca = _free(ca);
01615
01616 co = _free(co);
01617
01618 }
01619
01620 void rpmFreeRpmrc(void)
01621
01622
01623
01624
01625 {
01626 int i, j, k;
01627
01628
01629 if (platpat)
01630 for (i = 0; i < nplatpat; i++)
01631 platpat[i] = _free(platpat[i]);
01632 platpat = _free(platpat);
01633
01634 nplatpat = 0;
01635
01636 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
01637 tableType t;
01638 t = tables + i;
01639 if (t->equiv.list) {
01640 for (j = 0; j < t->equiv.count; j++)
01641 t->equiv.list[j].name = _free(t->equiv.list[j].name);
01642 t->equiv.list = _free(t->equiv.list);
01643 t->equiv.count = 0;
01644 }
01645 if (t->cache.cache) {
01646 for (j = 0; j < t->cache.size; j++) {
01647 machCacheEntry e;
01648 e = t->cache.cache + j;
01649 if (e == NULL)
01650 continue;
01651 e->name = _free(e->name);
01652 if (e->equivs) {
01653 for (k = 0; k < e->count; k++)
01654 e->equivs[k] = _free(e->equivs[k]);
01655 e->equivs = _free(e->equivs);
01656 }
01657 }
01658 t->cache.cache = _free(t->cache.cache);
01659 t->cache.size = 0;
01660 }
01661 if (t->defaults) {
01662 for (j = 0; j < t->defaultsLength; j++) {
01663 t->defaults[j].name = _free(t->defaults[j].name);
01664 t->defaults[j].defName = _free(t->defaults[j].defName);
01665 }
01666 t->defaults = _free(t->defaults);
01667 t->defaultsLength = 0;
01668 }
01669 if (t->canons) {
01670 for (j = 0; j < t->canonsLength; j++) {
01671 t->canons[j].name = _free(t->canons[j].name);
01672 t->canons[j].short_name = _free(t->canons[j].short_name);
01673 }
01674 t->canons = _free(t->canons);
01675 t->canonsLength = 0;
01676 }
01677 }
01678
01679 for (i = 0; i < RPMVAR_NUM; i++) {
01680 struct rpmvarValue * vp;
01681 while ((vp = values[i].next) != NULL) {
01682 values[i].next = vp->next;
01683 vp->value = _free(vp->value);
01684 vp->arch = _free(vp->arch);
01685 vp = _free(vp);
01686 }
01687 values[i].value = _free(values[i].value);
01688 values[i].arch = _free(values[i].arch);
01689 }
01690 current[OS] = _free(current[OS]);
01691 current[ARCH] = _free(current[ARCH]);
01692 defaultsInitialized = 0;
01693
01694 return;
01695
01696 }
01697
01703 static int rpmReadRC( const char * rcfiles)
01704
01705
01706
01707
01708 {
01709 char *myrcfiles, *r, *re;
01710 int rc;
01711
01712 if (!defaultsInitialized) {
01713 setDefaults();
01714 defaultsInitialized = 1;
01715 }
01716
01717 if (rcfiles == NULL)
01718 rcfiles = defrcfiles;
01719
01720
01721 rc = 0;
01722 for (r = myrcfiles = xstrdup(rcfiles); r && *r != '\0'; r = re) {
01723 char fn[4096];
01724 FD_t fd;
01725
01726
01727 for (re = r; (re = strchr(re, ':')) != NULL; re++) {
01728 if (!(re[1] == '/' && re[2] == '/'))
01729 break;
01730 }
01731 if (re && *re == ':')
01732 *re++ = '\0';
01733 else
01734 re = r + strlen(r);
01735
01736
01737 fn[0] = '\0';
01738 if (r[0] == '~' && r[1] == '/') {
01739 const char * home = getenv("HOME");
01740 if (home == NULL) {
01741
01742 if (rcfiles == defrcfiles && myrcfiles != r)
01743 continue;
01744 rpmError(RPMERR_RPMRC, _("Cannot expand %s\n"), r);
01745 rc = 1;
01746 break;
01747 }
01748 if (strlen(home) > (sizeof(fn) - strlen(r))) {
01749 rpmError(RPMERR_RPMRC, _("Cannot read %s, HOME is too large.\n"),
01750 r);
01751 rc = 1;
01752 break;
01753 }
01754 strcpy(fn, home);
01755 r++;
01756 }
01757 strncat(fn, r, sizeof(fn) - (strlen(fn) + 1));
01758 fn[sizeof(fn)-1] = '\0';
01759
01760
01761 fd = Fopen(fn, "r.fpio");
01762 if (fd == NULL || Ferror(fd)) {
01763
01764 if (rcfiles == defrcfiles && myrcfiles != r)
01765 continue;
01766 rpmError(RPMERR_RPMRC, _("Unable to open %s for reading: %s.\n"),
01767 fn, Fstrerror(fd));
01768 rc = 1;
01769 break;
01770 } else {
01771 rc = doReadRC(fd, fn);
01772 }
01773 if (rc) break;
01774 }
01775 myrcfiles = _free(myrcfiles);
01776 if (rc)
01777 return rc;
01778
01779 rpmSetMachine(NULL, NULL);
01780
01781 { const char *mfpath;
01782
01783 if ((mfpath = rpmGetVar(RPMVAR_MACROFILES)) != NULL) {
01784 mfpath = xstrdup(mfpath);
01785 rpmInitMacros(NULL, mfpath);
01786 mfpath = _free(mfpath);
01787 }
01788
01789 }
01790
01791 return rc;
01792 }
01793
01794 int rpmReadConfigFiles(const char * file, const char * target)
01795 {
01796 mode_t mode = 0022;
01797
01798 mode = umask(mode);
01799
01800
01801
01802 rpmRebuildTargetVars(&target, NULL);
01803
01804
01805 if (rpmReadRC(file)) return -1;
01806
01807
01808 rpmRebuildTargetVars(&target, NULL);
01809
01810
01811
01812 { const char *cpu = rpmExpand("%{_target_cpu}", NULL);
01813 const char *os = rpmExpand("%{_target_os}", NULL);
01814 rpmSetMachine(cpu, os);
01815 cpu = _free(cpu);
01816 os = _free(os);
01817 }
01818
01819 return 0;
01820 }
01821
01822 int rpmShowRC(FILE * fp)
01823 {
01824 struct rpmOption *opt;
01825 int i;
01826 machEquivTable equivTable;
01827
01828
01829 fprintf(fp, "ARCHITECTURE AND OS:\n");
01830 fprintf(fp, "build arch : %s\n", current[ARCH]);
01831
01832 fprintf(fp, "compatible build archs:");
01833 equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv;
01834 for (i = 0; i < equivTable->count; i++)
01835 fprintf(fp," %s", equivTable->list[i].name);
01836 fprintf(fp, "\n");
01837
01838 fprintf(fp, "build os : %s\n", current[OS]);
01839
01840 fprintf(fp, "compatible build os's :");
01841 equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv;
01842 for (i = 0; i < equivTable->count; i++)
01843 fprintf(fp," %s", equivTable->list[i].name);
01844 fprintf(fp, "\n");
01845
01846 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS);
01847 rpmSetMachine(NULL, NULL);
01848
01849 fprintf(fp, "install arch : %s\n", current[ARCH]);
01850 fprintf(fp, "install os : %s\n", current[OS]);
01851
01852 fprintf(fp, "compatible archs :");
01853 equivTable = &tables[RPM_MACHTABLE_INSTARCH].equiv;
01854 for (i = 0; i < equivTable->count; i++)
01855 fprintf(fp," %s", equivTable->list[i].name);
01856 fprintf(fp, "\n");
01857
01858 fprintf(fp, "compatible os's :");
01859 equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv;
01860 for (i = 0; i < equivTable->count; i++)
01861 fprintf(fp," %s", equivTable->list[i].name);
01862 fprintf(fp, "\n");
01863
01864 fprintf(fp, "\nRPMRC VALUES:\n");
01865 for (i = 0, opt = optionTable; i < optionTableSize; i++, opt++) {
01866 const char *s = rpmGetVar(opt->var);
01867 if (s != NULL || rpmIsVerbose())
01868 fprintf(fp, "%-21s : %s\n", opt->name, s ? s : "(not set)");
01869 }
01870 fprintf(fp, "\n");
01871
01872 fprintf(fp, "Features supported by rpmlib:\n");
01873 rpmShowRpmlibProvides(fp);
01874 fprintf(fp, "\n");
01875
01876 rpmDumpMacroTable(NULL, fp);
01877
01878 return 0;
01879 }
01880