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