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