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