home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
misc
/
src
/
rpm
/
lib
/
rpmrc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-17
|
25KB
|
983 lines
#include "config.h"
#include "miscfn.h"
#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <unistd.h>
#include "messages.h"
#include "misc.h"
#include "rpmlib.h"
#if HAVE_SYS_SYSTEMCFG_H
#include <sys/systemcfg.h>
#else
#define __power_pc() 0
#endif
struct machCacheEntry {
char * name;
int count;
char ** equivs;
int visited;
};
struct machCache {
struct machCacheEntry * cache;
int size;
};
struct machEquivInfo {
char * name;
int score;
};
struct machEquivTable {
int count;
struct machEquivInfo * list;
};
struct rpmvarValue {
char * value;
/* eventually, this arch will be replaced with a generic condition */
char * arch;
struct rpmvarValue * next;
};
struct rpmOption {
char * name;
int var;
int archSpecific, required;
struct rpmOptionValue * value;
};
struct defaultEntry {
char *name;
char *defName;
};
struct canonEntry {
char *name;
char *short_name;
short num;
};
/* tags are 'key'canon, 'key'translate, 'key'compat
for giggles, 'key'_canon, 'key'_compat, and 'key'_canon will also work */
struct tableType {
char * key;
int hasCanon, hasTranslate;
struct machEquivTable equiv;
struct machCache cache;
struct defaultEntry * defaults;
struct canonEntry * canons;
int defaultsLength;
int canonsLength;
};
static struct tableType tables[RPM_MACHTABLE_COUNT] = {
{ "arch", 1, 0 },
{ "os", 1, 0 },
{ "buildarch", 0, 1 },
{ "buildos", 0, 1 }
};
/* this *must* be kept in alphabetical order */
static struct rpmOption optionTable[] = {
{ "builddir", RPMVAR_BUILDDIR, 0, 0 },
{ "buildroot", RPMVAR_BUILDROOT, 0, 0 },
{ "dbpath", RPMVAR_DBPATH, 0, 1 },
{ "defaultdocdir", RPMVAR_DEFAULTDOCDIR, 0, 0 },
{ "distribution", RPMVAR_DISTRIBUTION, 0, 0 },
{ "excludedocs", RPMVAR_EXCLUDEDOCS, 0, 0 },
{ "fixperms", RPMVAR_FIXPERMS, 0, 1 },
{ "ftpport", RPMVAR_FTPPORT, 0, 0 },
{ "ftpproxy", RPMVAR_FTPPROXY, 0, 0 },
{ "gzipbin", RPMVAR_GZIPBIN, 0, 1 },
{ "messagelevel", RPMVAR_MESSAGELEVEL, 0, 0 },
{ "netsharedpath", RPMVAR_NETSHAREDPATH, 0, 0 },
{ "optflags", RPMVAR_OPTFLAGS, 1, 0 },
{ "packager", RPMVAR_PACKAGER, 0, 0 },
{ "pgp_name", RPMVAR_PGP_NAME, 0, 0 },
{ "pgp_path", RPMVAR_PGP_PATH, 0, 0 },
{ "provides", RPMVAR_PROVIDES, 0, 0 },
{ "require_distribution", RPMVAR_REQUIREDISTRIBUTION, 0, 0 },
{ "require_icon", RPMVAR_REQUIREICON, 0, 0 },
{ "require_vendor", RPMVAR_REQUIREVENDOR, 0, 0 },
{ "root", RPMVAR_ROOT, 0, 0 },
{ "rpmdir", RPMVAR_RPMDIR, 0, 0 },
{ "rpmfilename", RPMVAR_RPMFILENAME, 0, 1 },
{ "signature", RPMVAR_SIGTYPE, 0, 0 },
{ "sourcedir", RPMVAR_SOURCEDIR, 0, 0 },
{ "specdir", RPMVAR_SPECDIR, 0, 0 },
{ "srcrpmdir", RPMVAR_SRPMDIR, 0, 0 },
{ "timecheck", RPMVAR_TIMECHECK, 0, 0 },
{ "tmppath", RPMVAR_TMPPATH, 0, 1 },
{ "topdir", RPMVAR_TOPDIR, 0, 0 },
{ "vendor", RPMVAR_VENDOR, 0, 0 },
};
static int optionTableSize = sizeof(optionTable) / sizeof(*optionTable);
#define OS 0
#define ARCH 1
static char * current[2];
static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH };
static struct rpmvarValue values[RPMVAR_NUM];
/* prototypes */
static void defaultMachine(char ** arch, char ** os);
static int doReadRC(int fd, char * filename);
static int optionCompare(const void * a, const void * b);
static int addCanon(struct canonEntry **table, int *tableLen, char *line,
char *fn, int lineNum);
static int addDefault(struct defaultEntry **table, int *tableLen, char *line,
char *fn, int lineNum);
static void freeRpmVar(struct rpmvarValue * orig);
static void rpmSetVarArch(int var, char * val, char * arch);
static struct canonEntry *lookupInCanonTable(char *name,
struct canonEntry *table,
int tableLen);
static char *lookupInDefaultTable(char *name,
struct defaultEntry *table,
int tableLen);
static void setDefaults(void);
static void setPathDefault(int var, char * s);
static void rebuildCompatTables(int type, char * name);
/* compatiblity tables */
static int machCompatCacheAdd(char * name, char * fn, int linenum,
struct machCache * cache);
static struct machCacheEntry * machCacheFindEntry(struct machCache * cache,
char * key);
static struct machEquivInfo * machEquivSearch(
struct machEquivTable * table, char * name);
static void machAddEquiv(struct machEquivTable * table, char * name,
int distance);
static void machCacheEntryVisit(struct machCache * cache,
struct machEquivTable * table,
char * name,
int distance);
static void machFindEquivs(struct machCache * cache,
struct machEquivTable * table,
char * key);
static int optionCompare(const void * a, const void * b) {
return strcasecmp(((struct rpmOption *) a)->name,
((struct rpmOption *) b)->name);
}
static struct machCacheEntry * machCacheFindEntry(struct machCache * cache,
char * key) {
int i;
for (i = 0; i < cache->size; i++)
if (!strcmp(cache->cache[i].name, key)) return cache->cache + i;
return NULL;
}
static int machCompatCacheAdd(char * name, char * fn, int linenum,
struct machCache * cache) {
char * chptr, * equivs;
int delEntry = 0;
int i;
struct machCacheEntry * entry = NULL;
while (*name && isspace(*name)) name++;
chptr = name;
while (*chptr && *chptr != ':') chptr++;
if (!*chptr) {
rpmError(RPMERR_RPMRC, "missing second ':' at %s:%d", fn, linenum);
return 1;
} else if (chptr == name) {
rpmError(RPMERR_RPMRC, "missing architecture name at %s:%d", fn,
linenum);
return 1;
}
while (*chptr == ':' || isspace(*chptr)) chptr--;
*(++chptr) = '\0';
equivs = chptr + 1;
while (*equivs && isspace(*equivs)) equivs++;
if (!*equivs) {
delEntry = 1;
}
if (cache->size) {
entry = machCacheFindEntry(cache, name);
if (entry) {
for (i = 0; i < entry->count; i++)
free(entry->equivs[i]);
if (entry->count) free(entry->equivs);
entry->count = 0;
}
}
if (!entry) {
cache->cache = realloc(cache->cache,
(cache->size + 1) * sizeof(*cache->cache));
entry = cache->cache + cache->size++;
entry->name = strdup(name);
entry->count = 0;
entry->visited = 0;
}
if (delEntry) return 0;
chptr = strtok(equivs, " ");
while (chptr) {
if (strlen(chptr)) { /* does strtok() return "" ever?? */
if (entry->count)
entry->equivs = realloc(entry->equivs, sizeof(*entry->equivs)
* (entry->count + 1));
else
entry->equivs = malloc(sizeof(*entry->equivs));
entry->equivs[entry->count] = strdup(chptr);
entry->count++;
}
chptr = strtok(NULL, " ");
}
return 0;
}
static struct machEquivInfo * machEquivSearch(
struct machEquivTable * table, char * name) {
int i;
for (i = 0; i < table->count; i++)
if (!strcmp(table->list[i].name, name))
return table->list + i;
return NULL;
}
static void machAddEquiv(struct machEquivTable * table, char * name,
int distance) {
struct machEquivInfo * equiv;
equiv = machEquivSearch(table, name);
if (!equiv) {
if (table->count)
table->list = realloc(table->list, (table->count + 1)
* sizeof(*table->list));
else
table->list = malloc(sizeof(*table->list));
table->list[table->count].name = strdup(name);
table->list[table->count++].score = distance;
}
}
static void machCacheEntryVisit(struct machCache * cache,
struct machEquivTable * table,
char * name,
int distance) {
struct machCacheEntry * entry;
int i;
entry = machCacheFindEntry(cache, name);
if (!entry || entry->visited) return;
entry->visited = 1;
for (i = 0; i < entry->count; i++) {
machAddEquiv(table, entry->equivs[i], distance);
}
for (i = 0; i < entry->count; i++) {
machCacheEntryVisit(cache, table, entry->equivs[i], distance + 1);
}
};
static void machFindEquivs(struct machCache * cache,
struct machEquivTable * table,
char * key) {
int i;
for (i = 0; i < cache->size; i++)
cache->cache[i].visited = 0;
table->count = 0;
/* We have a general graph built using strings instead of pointers.
Yuck. We have to start at a point at traverse it, remembering how
far away everything is. */
machAddEquiv(table, key, 1);
machCacheEntryVisit(cache, table, key, 2);
}
static int addCanon(struct canonEntry **table, int *tableLen, char *line,
char *fn, int lineNum) {
struct canonEntry *t;
char *s, *s1;
if (! *tableLen) {
*tableLen = 2;
*table = malloc(2 * sizeof(struct canonEntry));
} else {
(*tableLen) += 2;
*table = realloc(*table, sizeof(struct canonEntry) * (*tableLen));
}
t = & ((*table)[*tableLen - 2]);
t->name = strtok(line, ": \t");
t->short_name = strtok(NULL, " \t");
s = strtok(NULL, " \t");
if (! (t->name && t->short_name && s)) {
rpmError(RPMERR_RPMRC, "Incomplete data line at %s:%d", fn, lineNum);
return RPMERR_RPMRC;
}
if (strtok(NULL, " \t")) {
rpmError(RPMERR_RPMRC, "Too many args in data line at %s:%d",
fn, lineNum);
return RPMERR_RPMRC;
}
t->num = strtoul(s, &s1, 10);
if ((*s1) || (s1 == s) || (t->num == ULONG_MAX)) {
rpmError(RPMERR_RPMRC, "Bad arch/os number: %s (%s:%d)", s,
fn, lineNum);
return(RPMERR_RPMRC);
}
t->name = strdup(t->name);
t->short_name = strdup(t->short_name);
/* From A B C entry */
/* Add B B C entry */
t[1].name = strdup(t->short_name);
t[1].short_name = strdup(t->short_name);
t[1].num = t->num;
return 0;
}
static int addDefault(struct defaultEntry **table, int *tableLen, char *line,
char *fn, int lineNum) {
struct defaultEntry *t;
if (! *tableLen) {
*tableLen = 1;
*table = malloc(sizeof(struct defaultEntry));
} else {
(*tableLen)++;
*table = realloc(*table, sizeof(struct defaultEntry) * (*tableLen));
}
t = & ((*table)[*tableLen - 1]);
t->name = strtok(line, ": \t");
t->defName = strtok(NULL, " \t");
if (! (t->name && t->defName)) {
rpmError(RPMERR_RPMRC, "Incomplete default line at %s:%d", fn, lineNum);
return RPMERR_RPMRC;
}
if (strtok(NULL, " \t")) {
rpmError(RPMERR_RPMRC, "Too many args in default line at %s:%d",
fn, lineNum);
return RPMERR_RPMRC;
}
t->name = strdup(t->name);
t->defName = strdup(t->defName);
return 0;
}
static struct canonEntry *lookupInCanonTable(char *name,
struct canonEntry *table,
int tableLen) {
while (tableLen) {
tableLen--;
if (!strcmp(name, table[tableLen].name)) {
return &(table[tableLen]);
}
}
return NULL;
}
static char *lookupInDefaultTable(char *name, struct defaultEntry *table,
int tableLen) {
while (tableLen) {
tableLen--;
if (!strcmp(name, table[tableLen].name)) {
return table[tableLen].defName;
}
}
return name;
}
int rpmReadConfigFiles(char * file, char * arch, char * os, int building) {
if (rpmReadRC(file)) return -1;
if (building)
rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
rpmSetMachine(arch, os);
return 0;
}
static void setPathDefault(int var, char * s) {
char * topdir;
char * fn;
if (rpmGetVar(var)) return;
topdir = rpmGetVar(RPMVAR_TOPDIR);
if (!topdir) topdir = rpmGetVar(RPMVAR_TMPPATH);
fn = alloca(strlen(topdir) + strlen(s) + 2);
strcpy(fn, topdir);
if (fn[strlen(topdir) - 1] != '/')
strcat(fn, "/");
strcat(fn, s);
rpmSetVar(var, fn);
}
static void setDefaults(void) {
rpmSetVar(RPMVAR_OPTFLAGS, "-O2");
rpmSetVar(RPMVAR_SIGTYPE, "none");
rpmSetVar(RPMVAR_DEFAULTDOCDIR, "/usr/doc");
rpmSetVar(RPMVAR_TOPDIR, "/usr/src/redhat");
}
int rpmReadRC(char * file) {
int fd;
char * fn;
char * home;
int rc = 0;
static int first = 1;
if (first) {
setDefaults();
first = 0;
}
fd = open(LIBRPMRC_FILENAME, O_RDONLY);
if (fd > 0) {
rc = doReadRC(fd, LIBRPMRC_FILENAME);
close(fd);
if (rc) return rc;
} else {
rpmError(RPMERR_RPMRC, "Unable to open %s for reading: %s.",
LIBRPMRC_FILENAME, strerror(errno));
return 1;
}
if (file)
fn = file;
else
fn = "/etc/rpmrc";
fd = open(fn, O_RDONLY);
if (fd > 0) {
rc = doReadRC(fd, fn);
close(fd);
if (rc) return rc;
} else if (file) {
rpmError(RPMERR_RPMRC, "Unable to open %s for reading: %s.", file,
strerror(errno));
return 1;
}
if (!file) {
home = getenv("HOME");
if (home) {
fn = alloca(strlen(home) + 8);
strcpy(fn, home);
strcat(fn, "/.rpmrc");
fd = open(fn, O_RDONLY);
if (fd > 0) {
rc |= doReadRC(fd, fn);
close(fd);
if (rc) return rc;
}
}
}
rpmSetMachine(NULL, NULL);
setPathDefault(RPMVAR_BUILDDIR, "BUILD");
setPathDefault(RPMVAR_RPMDIR, "RPMS");
setPathDefault(RPMVAR_SRPMDIR, "SRPMS");
setPathDefault(RPMVAR_SOURCEDIR, "SOURCES");
setPathDefault(RPMVAR_SPECDIR, "SPECS");
return 0;
}
static int doReadRC(int fd, char * filename) {
struct stat sb;
char * buf;
char * start, * chptr, * next, * rest;
int linenum = 0;
struct rpmOption searchOption, * option;
int i;
int gotit;
fstat(fd, &sb);
next = buf = alloca(sb.st_size + 2);
if (read(fd, buf, sb.st_size) != sb.st_size) {
rpmError(RPMERR_RPMRC, "Failed to read %s: %s.", filename,
strerror(errno));
return 1;
}
buf[sb.st_size] = '\n';
buf[sb.st_size + 1] = '\0';
while (*next) {
linenum++;
chptr = start = next;
while (*chptr != '\n') chptr++;
*chptr = '\0';
next = chptr + 1;
while (isspace(*start)) start++;
/* we used to allow comments to begin anywhere, but not anymore */
if (*start == '#' || !*start) continue;
chptr = start;
while (!isspace(*chptr) && *chptr != ':' && *chptr) chptr++;
if (isspace(*chptr)) {
*chptr++ = '\0';
while (isspace(*chptr) && *chptr != ':' && *chptr) chptr++;
}
if (*chptr != ':') {
rpmError(RPMERR_RPMRC, "missing ':' at %s:%d", filename, linenum);
return 1;
}
*chptr++ = '\0';
searchOption.name = start;
option = bsearch(&searchOption, optionTable, optionTableSize,
sizeof(struct rpmOption), optionCompare);
if (option) {
start = chptr;
while (isspace(*start) && *start) start++;
if (! *start) {
rpmError(RPMERR_RPMRC, "missing argument for %s at %s:%d",
option->name, filename, linenum);
return 1;
}
if (option->archSpecific) {
chptr = start;
while (!isspace(*chptr) && *chptr) chptr++;
if (!*chptr) {
rpmError(RPMERR_RPMRC,
"missing architecture for %s at %s:%d",
option->name, filename, linenum);
return 1;
}
*chptr++ = '\0';
while (isspace(*chptr) && *chptr) chptr++;
if (!*chptr) {
rpmError(RPMERR_RPMRC,
"missing argument for %s at %s:%d",
option->name, filename, linenum);
return 1;
}
rpmSetVarArch(option->var, chptr, start);
} else {
rpmSetVarArch(option->var, start, NULL);
}
} else {
gotit = 0;
for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
if (!strncmp(tables[i].key, start, strlen(tables[i].key)))
break;
}
if (i < RPM_MACHTABLE_COUNT) {
rest = start + strlen(tables[i].key);
if (*rest == '_') rest++;
if (!strcmp(rest, "compat")) {
if (machCompatCacheAdd(chptr, filename, linenum,
&tables[i].cache))
return 1;
gotit = 1;
} else if (tables[i].hasTranslate &&
!strcmp(rest, "translate")) {
if (addDefault(&tables[i].defaults,
&tables[i].defaultsLength,
chptr, filename, linenum))
return 1;
gotit = 1;
} else if (tables[i].hasCanon &&
!strcmp(rest, "canon")) {
if (addCanon(&tables[i].canons, &tables[i].canonsLength,
chptr, filename, linenum))
return 1;
gotit = 1;
}
}
if (!gotit) {
rpmError(RPMERR_RPMRC, "bad option '%s' at %s:%d",
start, filename, linenum);
}
}
}
return 0;
}
static void defaultMachine(char ** arch, char ** os) {
static struct utsname un;
static int gotDefaults = 0;
char * chptr;
struct canonEntry * canon;
if (!gotDefaults) {
uname(&un);
if (!strcmp(un.sysname, "AIX")) {
strcpy(un.machine, __power_pc() ? "ppc" : "rs6000");
} else if (!strncmp(un.sysname, "IP", 2)) {
un.sysname[2] = '\0';
}
/* get rid of the hyphens in the sysname */
chptr = un.machine;
while (*chptr++)
if (*chptr == '/') *chptr = '-';
#if defined(__hpux) && defined(_SC_CPU_VERSION)
{
int cpu_version = sysconf(_SC_CPU_VERSION);
#if defined(CPU_HP_MC68020)
if (cpu_version == CPU_HP_MC68020)
strcpy(un.machine, "m68k");
#endif
#if defined(CPU_HP_MC68030)
if (cpu_version == CPU_HP_MC68030)
strcpy(un.machine, "m68k");
#endif
#if defined(CPU_HP_MC68040)
if (cpu_version == CPU_HP_MC68040)
strcpy(un.machine, "m68k");
#endif
#if defined(CPU_PA_RISC1_0)
if (cpu_version == CPU_PA_RISC1_0)
strcpy(un.machine, "parisc");
#endif
#if defined(CPU_PA_RISC1_1)
if (cpu_version == CPU_PA_RISC1_1)
strcpy(un.machine, "parisc");
#endif
#if defined(CPU_PA_RISC1_2)
if (cpu_version == CPU_PA_RISC1_2)
strcpy(un.machine, "parisc");
#endif
}
#endif
/* the uname() result goes through the arch_canon table */
canon = lookupInCanonTable(un.machine,
tables[RPM_MACHTABLE_INSTARCH].canons,
tables[RPM_MACHTABLE_INSTARCH].canonsLength);
if (canon)
strcpy(un.machine, canon->short_name);
canon = lookupInCanonTable(un.sysname,
tables[RPM_MACHTABLE_INSTOS].canons,
tables[RPM_MACHTABLE_INSTOS].canonsLength);
if (canon)
strcpy(un.sysname, canon->short_name);
}
if (arch) *arch = un.machine;
if (os) *os = un.sysname;
}
static char * rpmGetVarArch(int var, char * arch) {
struct rpmvarValue * next;
if (!arch) arch = current[ARCH];
if (arch) {
next = &values[var];
while (next) {
if (next->arch && !strcmp(next->arch, arch)) return next->value;
next = next->next;
}
}
next = values + var;
while (next && next->arch) next = next->next;
return next ? next->value : NULL;
}
char *rpmGetVar(int var)
{
return rpmGetVarArch(var, NULL);
}
int rpmGetBooleanVar(int var) {
char * val;
int num;
char * chptr;
val = rpmGetVar(var);
if (!val) return 0;
if (val[0] == 'y' || val[0] == 'Y') return 1;
num = strtol(val, &chptr, 0);
if (chptr && *chptr == '\0') {
return num != 0;
}
return 0;
}
void rpmSetVar(int var, char *val) {
freeRpmVar(&values[var]);
values[var].arch = NULL;
values[var].next = NULL;
if (val)
values[var].value = strdup(val);
else
values[var].value = NULL;
}
/* this doesn't free the passed pointer! */
static void freeRpmVar(struct rpmvarValue * orig) {
struct rpmvarValue * next, * var = orig;
while (var) {
next = var->next;
if (var->arch) free(var->arch);
if (var->value) free(var->value);
if (var != orig) free(var);
var = next;
}
}
static void rpmSetVarArch(int var, char * val, char * arch) {
struct rpmvarValue * next = values + var;
if (next->value) {
if (arch) {
while (next->next) {
if (next->arch && !strcmp(next->arch, arch)) break;
next = next->next;
}
} else {
while (next->next) {
if (!next->arch) break;
next = next->next;
}
}
if (next->arch && arch && !strcmp(next->arch, arch)) {
if (next->value) free(next->value);
if (next->arch) free(next->arch);
} else if (next->arch || arch) {
next->next = malloc(sizeof(*next->next));
next = next->next;
next->next = NULL;
}
}
next->value = strdup(val);
if (arch)
next->arch = strdup(arch);
else
next->arch = NULL;
}
void rpmSetTables(int archTable, int osTable) {
char * arch, * os;
defaultMachine(&arch, &os);
if (currTables[ARCH] != archTable) {
currTables[ARCH] = archTable;
rebuildCompatTables(ARCH, arch);
}
if (currTables[OS] != osTable) {
currTables[OS] = osTable;
rebuildCompatTables(OS, os);
}
}
int rpmMachineScore(int type, char * name) {
struct machEquivInfo * info;
info = machEquivSearch(&tables[type].equiv, name);
if (info)
return info->score;
else
return 0;
}
void rpmSetMachine(char * arch, char * os) {
int transOs = os == NULL;
int transArch = arch == NULL;
char * realArch, * realOs;
defaultMachine(&realArch, &realOs);
if (!arch)
arch = realArch;
if (!os)
os = realOs;
if (transArch && tables[currTables[ARCH]].hasTranslate)
arch = lookupInDefaultTable(arch,
tables[currTables[ARCH]].defaults,
tables[currTables[ARCH]].defaultsLength);
if (transOs && tables[currTables[OS]].hasTranslate)
os = lookupInDefaultTable(os,
tables[currTables[OS]].defaults,
tables[currTables[OS]].defaultsLength);
if (!current[ARCH] || strcmp(arch, current[ARCH])) {
if (current[ARCH]) free(current[ARCH]);
current[ARCH] = strdup(arch);
rebuildCompatTables(ARCH, realArch);
}
if (!current[OS] || strcmp(os, current[OS])) {
if (current[OS]) free(current[OS]);
current[OS] = strdup(os);
rebuildCompatTables(OS, realOs);
}
}
static void rebuildCompatTables(int type, char * name) {
machFindEquivs(&tables[currTables[type]].cache,
&tables[currTables[type]].equiv,
name);
}
static void getMachineInfo(int type, char ** name, int * num) {
struct canonEntry * canon;
if (!tables[currTables[type]].hasCanon) {
if (num) *num = 255;
if (name) *name = current[type];
return;
}
canon = lookupInCanonTable(current[type],
tables[currTables[type]].canons,
tables[currTables[type]].canonsLength);
if (canon) {
if (num) *num = canon->num;
if (name) *name = canon->short_name;
} else {
if (num) *num = 255;
if (name) *name = current[type];
rpmMessage(RPMMESS_WARNING, "Unknown system: %s\n", current[type]);
rpmMessage(RPMMESS_WARNING, "Please contact rpm-list@redhat.com\n");
}
}
void rpmGetArchInfo(char ** name, int * num) {
getMachineInfo(ARCH, name, num);
}
void rpmGetOsInfo(char ** name, int * num) {
getMachineInfo(OS, name, num);
}
int rpmShowRC(FILE *f)
{
struct rpmOption *opt;
int count = 0;
char *s;
int i;
struct machEquivTable * equivTable;
/* the caller may set the build arch which should be printed here */
fprintf(f, "ARCHITECTURE AND OS:\n");
fprintf(f, "build arch : %s\n", current[ARCH]);
fprintf(f, "compatible build archs:");
equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv;
for (i = 0; i < equivTable->count; i++)
fprintf(f," %s", equivTable->list[i].name);
fprintf(f, "\n");
fprintf(f, "build os : %s\n", current[OS]);
fprintf(f, "compatible build os's :");
equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv;
for (i = 0; i < equivTable->count; i++)
fprintf(f," %s", equivTable->list[i].name);
fprintf(f, "\n");
rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS);
rpmSetMachine(NULL, NULL);
fprintf(f, "install arch : %s\n", current[ARCH]);
fprintf(f, "install os : %s\n", current[OS]);
fprintf(f, "compatible archs :");
equivTable = &tables[RPM_MACHTABLE_INSTARCH].equiv;
for (i = 0; i < equivTable->count; i++)
fprintf(f," %s", equivTable->list[i].name);
fprintf(f, "\n");
fprintf(f, "compatible os's :");
equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv;
for (i = 0; i < equivTable->count; i++)
fprintf(f," %s", equivTable->list[i].name);
fprintf(f, "\n");
fprintf(f, "RPMRC VALUES:\n");
opt = optionTable;
while (count < optionTableSize) {
s = rpmGetVar(opt->var);
fprintf(f, "%-21s : %s\n", opt->name, s ? s : "(not set)");
opt++;
count++;
}
return 0;
}