diff options
Diffstat (limited to 'lib/rpmrc.c')
-rw-r--r-- | lib/rpmrc.c | 745 |
1 files changed, 462 insertions, 283 deletions
diff --git a/lib/rpmrc.c b/lib/rpmrc.c index 7638e8114..cada3f788 100644 --- a/lib/rpmrc.c +++ b/lib/rpmrc.c @@ -1,6 +1,7 @@ #include "system.h" #include <stdarg.h> +#include <pthread.h> #if defined(__linux__) #include <elf.h> @@ -11,7 +12,6 @@ #if HAVE_SYS_UTSNAME_H #include <sys/utsname.h> #endif -#include <netdb.h> #include <ctype.h> /* XXX for /etc/rpm/platform contents */ #if HAVE_SYS_SYSTEMCFG_H @@ -20,32 +20,32 @@ #define __power_pc() 0 #endif +#ifdef HAVE_SYS_AUXV_H +#include <sys/auxv.h> +#endif + #include <rpm/rpmlib.h> /* RPM_MACTABLE*, Rc-prototypes */ #include <rpm/rpmmacro.h> #include <rpm/rpmfileutil.h> #include <rpm/rpmstring.h> #include <rpm/rpmlog.h> +#include <rpm/argv.h> #include "rpmio/rpmlua.h" #include "rpmio/rpmio_internal.h" /* XXX for rpmioSlurp */ #include "lib/misc.h" #include "lib/rpmliblua.h" +#include "lib/rpmug.h" #include "debug.h" static const char * defrcfiles = NULL; const char * macrofiles = NULL; -static const char * const platform = SYSCONFDIR "/rpm/platform"; -static char ** platpat = NULL; -static int nplatpat = 0; - -typedef char * cptr_t; - typedef struct machCacheEntry_s { char * name; int count; - cptr_t * equivs; + char ** equivs; int visited; } * machCacheEntry; @@ -111,13 +111,6 @@ typedef struct tableType_s { int canonsLength; } * tableType; -static struct tableType_s tables[RPM_MACHTABLE_COUNT] = { - { "arch", 1, 0 }, - { "os", 1, 0 }, - { "buildarch", 0, 1 }, - { "buildos", 0, 1 } -}; - /* XXX get rid of this stuff... */ /* Stuff for maintaining "variables" like SOURCEDIR, BUILDDIR, etc */ #define RPMVAR_OPTFLAGS 3 @@ -142,23 +135,58 @@ static const size_t optionTableSize = sizeof(optionTable) / sizeof(*optionTable) #define OS 0 #define ARCH 1 -static cptr_t current[2]; +typedef struct rpmrcCtx_s * rpmrcCtx; +struct rpmrcCtx_s { + ARGV_t platpat; + char *current[2]; + int currTables[2]; + struct rpmvarValue values[RPMVAR_NUM]; + struct tableType_s tables[RPM_MACHTABLE_COUNT]; + int machDefaults; + int pathDefaults; + pthread_rwlock_t lock; +}; -static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH }; +/* prototypes */ +static rpmRC doReadRC(rpmrcCtx ctx, const char * urlfn); -static struct rpmvarValue values[RPMVAR_NUM]; +static void rpmSetVarArch(rpmrcCtx ctx, + int var, const char * val, const char * arch); -static int defaultsInitialized = 0; +static void rebuildCompatTables(rpmrcCtx ctx, int type, const char * name); -/* prototypes */ -static rpmRC doReadRC(const char * urlfn); +static void rpmRebuildTargetVars(rpmrcCtx ctx, const char **target, const char ** canontarget); -static void rpmSetVarArch(int var, const char * val, - const char * arch); +/* Force context (lock) acquisition through a function */ +static rpmrcCtx rpmrcCtxAcquire(int write) +{ + static struct rpmrcCtx_s _globalCtx = { + .lock = PTHREAD_RWLOCK_INITIALIZER, + .currTables = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH }, + .tables = { + { "arch", 1, 0 }, + { "os", 1, 0 }, + { "buildarch", 0, 1 }, + { "buildos", 0, 1 } + }, + }; + rpmrcCtx ctx = &_globalCtx; + + /* XXX: errors should be handled */ + if (write) + pthread_rwlock_wrlock(&ctx->lock); + else + pthread_rwlock_rdlock(&ctx->lock); -static void rebuildCompatTables(int type, const char * name); + return ctx; +} -static void rpmRebuildTargetVars(const char **target, const char ** canontarget); +/* Release context (lock) */ +static rpmrcCtx rpmrcCtxRelease(rpmrcCtx ctx) +{ + pthread_rwlock_unlock(&ctx->lock); + return NULL; +} static int optionCompare(const void * a, const void * b) { @@ -452,7 +480,7 @@ static void setDefaults(void) } /* FIX: se usage inconsistent, W2DO? */ -static rpmRC doReadRC(const char * urlfn) +static rpmRC doReadRC(rpmrcCtx ctx, const char * urlfn) { char *s; char *se, *next, *buf = NULL, *fn; @@ -519,7 +547,7 @@ static rpmRC doReadRC(const char * urlfn) while (*se && !risspace(*se)) se++; if (*se != '\0') *se = '\0'; - if (doReadRC(s)) { + if (doReadRC(ctx, s)) { rpmlog(RPMLOG_ERR, _("cannot open %s at %s:%d: %m\n"), s, fn, linenum); goto exit; @@ -551,48 +579,49 @@ static rpmRC doReadRC(const char * urlfn) /* Only add macros if appropriate for this arch */ if (option->macroize && - (arch == NULL || rstreq(arch, current[ARCH]))) { + (arch == NULL || rstreq(arch, ctx->current[ARCH]))) { char *n, *name; n = name = xmalloc(strlen(option->name)+2); if (option->localize) *n++ = '_'; strcpy(n, option->name); - addMacro(NULL, name, NULL, val, RMIL_RPMRC); + rpmPushMacro(NULL, name, NULL, val, RMIL_RPMRC); free(name); } - rpmSetVarArch(option->var, val, arch); + rpmSetVarArch(ctx, option->var, val, arch); fn = _free(fn); - } else { /* For arch/os compatibilty tables ... */ + } else { /* For arch/os compatibility tables ... */ int gotit; int i; gotit = 0; for (i = 0; i < RPM_MACHTABLE_COUNT; i++) { - if (rstreqn(tables[i].key, s, strlen(tables[i].key))) + if (rstreqn(ctx->tables[i].key, s, strlen(ctx->tables[i].key))) break; } if (i < RPM_MACHTABLE_COUNT) { - const char *rest = s + strlen(tables[i].key); + const char *rest = s + strlen(ctx->tables[i].key); if (*rest == '_') rest++; if (rstreq(rest, "compat")) { if (machCompatCacheAdd(se, fn, linenum, - &tables[i].cache)) + &ctx->tables[i].cache)) goto exit; gotit = 1; - } else if (tables[i].hasTranslate && + } else if (ctx->tables[i].hasTranslate && rstreq(rest, "translate")) { - if (addDefault(&tables[i].defaults, - &tables[i].defaultsLength, + if (addDefault(&ctx->tables[i].defaults, + &ctx->tables[i].defaultsLength, se, fn, linenum)) goto exit; gotit = 1; - } else if (tables[i].hasCanon && + } else if (ctx->tables[i].hasCanon && rstreq(rest, "canon")) { - if (addCanon(&tables[i].canons, &tables[i].canonsLength, + if (addCanon(&ctx->tables[i].canons, + &ctx->tables[i].canonsLength, se, fn, linenum)) goto exit; gotit = 1; @@ -618,7 +647,7 @@ exit: /** */ -static rpmRC rpmPlatform(const char * platform) +static rpmRC rpmPlatform(rpmrcCtx ctx, const char * platform) { const char *cpu = NULL, *vendor = NULL, *os = NULL, *gnu = NULL; uint8_t * b = NULL; @@ -651,10 +680,7 @@ static rpmRC rpmPlatform(const char * platform) while (--t > p && isspace(*t)) *t = '\0'; if (t > p) { - platpat = xrealloc(platpat, (nplatpat + 2) * sizeof(*platpat)); - platpat[nplatpat] = xstrdup(p); - nplatpat++; - platpat[nplatpat] = NULL; + argvAdd(&ctx->platpat, p); } continue; } @@ -690,14 +716,14 @@ static rpmRC rpmPlatform(const char * platform) if (*p != '\0') *p = '\0'; } - addMacro(NULL, "_host_cpu", NULL, cpu, -1); - addMacro(NULL, "_host_vendor", NULL, vendor, -1); - addMacro(NULL, "_host_os", NULL, os, -1); + rpmPushMacro(NULL, "_host_cpu", NULL, cpu, -1); + rpmPushMacro(NULL, "_host_vendor", NULL, vendor, -1); + rpmPushMacro(NULL, "_host_os", NULL, os, -1); - platpat = xrealloc(platpat, (nplatpat + 2) * sizeof(*platpat)); - platpat[nplatpat] = rpmExpand("%{_host_cpu}-%{_host_vendor}-%{_host_os}", (gnu && *gnu ? "-" : NULL), gnu, NULL); - nplatpat++; - platpat[nplatpat] = NULL; + char *plat = rpmExpand("%{_host_cpu}-%{_host_vendor}-%{_host_os}", + (gnu && *gnu ? "-" : NULL), gnu, NULL); + argvAdd(&ctx->platpat, plat); + free(plat); init_platform++; } @@ -789,8 +815,21 @@ static inline int RPMClass(void) cpu = (tfms>>8)&15; + if (cpu == 5 + && cpuid_ecx(0) == '68xM' + && cpuid_edx(0) == 'Teni' + && (cpuid_edx(1) & ((1<<8)|(1<<15))) == ((1<<8)|(1<<15))) { + sigaction(SIGILL, &oldsa, NULL); + return 6; /* has CX8 and CMOV */ + } + sigaction(SIGILL, &oldsa, NULL); +#define USER686 ((1<<4) | (1<<8) | (1<<15)) + /* Transmeta Crusoe CPUs say that their CPU family is "5" but they have enough features for i686. */ + if (cpu == 5 && (cap & USER686) == USER686) + return 6; + if (cpu < 6) return cpu; @@ -912,13 +951,19 @@ static int is_geode(void) #if defined(__linux__) /** - * Populate rpmat structure with parsed info from /proc/self/auxv + * Populate rpmat structure with auxv values */ -static void parse_auxv(void) +static void read_auxv(void) { static int oneshot = 1; if (oneshot) { +#ifdef HAVE_GETAUXVAL + rpmat.platform = (char *) getauxval(AT_PLATFORM); + if (!rpmat.platform) + rpmat.platform = ""; + rpmat.hwcap = getauxval(AT_HWCAP); +#else rpmat.platform = ""; int fd = open("/proc/self/auxv", O_RDONLY); @@ -943,6 +988,7 @@ static void parse_auxv(void) } close(fd); } +#endif oneshot = 0; /* only try once even if it fails */ } return; @@ -951,22 +997,21 @@ static void parse_auxv(void) /** */ -static void defaultMachine(const char ** arch, - const char ** os) +static void defaultMachine(rpmrcCtx ctx, const char ** arch, const char ** os) { + const char * const platform_path = SYSCONFDIR "/rpm/platform"; static struct utsname un; - static int gotDefaults = 0; char * chptr; canonEntry canon; int rc; #if defined(__linux__) /* Populate rpmat struct with hw info */ - parse_auxv(); + read_auxv(); #endif - while (!gotDefaults) { - if (!rpmPlatform(platform)) { + while (!ctx->machDefaults) { + if (!rpmPlatform(ctx, platform_path)) { char * s = rpmExpand("%{_host_cpu}", NULL); if (s) { rstrlcpy(un.machine, s, sizeof(un.machine)); @@ -977,7 +1022,7 @@ static void defaultMachine(const char ** arch, rstrlcpy(un.sysname, s, sizeof(un.sysname)); free(s); } - gotDefaults = 1; + ctx->machDefaults = 1; break; } rc = uname(&un); @@ -988,11 +1033,15 @@ static void defaultMachine(const char ** arch, strcpy(un.machine, __power_pc() ? "ppc" : "rs6000"); sprintf(un.sysname,"aix%s.%s", un.version, un.release); } - else if(rstreq(un.sysname, "Darwin")) { -#ifdef __ppc__ + else if (rstreq(un.sysname, "Darwin")) { +#if defined(__ppc__) strcpy(un.machine, "ppc"); -#else ifdef __i386__ +#elif defined(__i386__) strcpy(un.machine, "i386"); +#elif defined(__x86_64__) + strcpy(un.machine, "x86_64"); +#else + #warning "No architecture defined! Automatic detection may not work!" #endif } else if (rstreq(un.sysname, "SunOS")) { @@ -1020,12 +1069,54 @@ static void defaultMachine(const char ** arch, # if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) /* little endian */ - strcpy(un.machine, "mipsel"); +# if defined(__mips64) + /* 64-bit */ +# if !defined(__mips_isa_rev) || __mips_isa_rev < 6 + /* r1-r5 */ + strcpy(un.machine, "mips64el"); +# else + /* r6 */ + strcpy(un.machine, "mips64r6el"); +# endif +# else + /* 32-bit */ +# if !defined(__mips_isa_rev) || __mips_isa_rev < 6 + /* r1-r5 */ + strcpy(un.machine, "mipsel"); +# else + /* r6 */ + strcpy(un.machine, "mipsr6el"); +# endif +# endif # elif defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) /* big endian */ - strcpy(un.machine, "mips"); +# if defined(__mips64) + /* 64-bit */ +# if !defined(__mips_isa_rev) || __mips_isa_rev < 6 + /* r1-r5 */ + strcpy(un.machine, "mips64"); +# else + /* r6 */ + strcpy(un.machine, "mips64r6"); +# endif +# else + /* 32-bit */ +# if !defined(__mips_isa_rev) || __mips_isa_rev < 6 + /* r1-r5 */ + strcpy(un.machine, "mips"); +# else + /* r6 */ + strcpy(un.machine, "mipsr6"); +# endif +# endif # endif +#if defined(__linux__) + /* in linux, lets rename parisc to hppa */ + if (rstreq(un.machine, "parisc")) + strcpy(un.machine, "hppa"); +#endif + # if defined(__hpux) && defined(_SC_CPU_VERSION) { # if !defined(CPU_PA_RISC1_2) @@ -1069,6 +1160,9 @@ static void defaultMachine(const char ** arch, # endif /* hpux */ # if defined(__linux__) && defined(__sparc__) +# if !defined(HWCAP_SPARC_BLKINIT) +# define HWCAP_SPARC_BLKINIT 0x00000040 +# endif if (rstreq(un.machine, "sparc")) { #define PERS_LINUX 0x00000000 #define PERS_LINUX_32BIT 0x00800000 @@ -1088,10 +1182,20 @@ static void defaultMachine(const char ** arch, } personality(oldpers); } + + /* This is how glibc detects Niagara so... */ + if (rpmat.hwcap & HWCAP_SPARC_BLKINIT) { + if (rstreq(un.machine, "sparcv9") || rstreq(un.machine, "sparc")) { + strcpy(un.machine, "sparcv9v"); + } else if (rstreq(un.machine, "sparc64")) { + strcpy(un.machine, "sparc64v"); + } + } } # endif /* sparc*-linux */ # if defined(__linux__) && defined(__powerpc__) +# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ { int powerlvl; if (!rstreq(un.machine, "ppc") && @@ -1100,8 +1204,43 @@ static void defaultMachine(const char ** arch, strcpy(un.machine, "ppc64p7"); } } +# endif /* __ORDER_BIG_ENDIAN__ */ # endif /* ppc64*-linux */ +# if defined(__linux__) && defined(__arm__) && defined(__ARM_PCS_VFP) +# if !defined(HWCAP_ARM_VFP) +# define HWCAP_ARM_VFP (1 << 6) +# endif +# if !defined(HWCAP_ARM_NEON) +# define HWCAP_ARM_NEON (1 << 12) +# endif +# if !defined(HWCAP_ARM_VFPv3) +# define HWCAP_ARM_VFPv3 (1 << 13) +# endif + if (rstreq(un.machine, "armv7l")) { + if (rpmat.hwcap & HWCAP_ARM_VFPv3) { + if (rpmat.hwcap & HWCAP_ARM_NEON) + strcpy(un.machine, "armv7hnl"); + else + strcpy(un.machine, "armv7hl"); + } + } else if (rstreq(un.machine, "armv6l")) { + if (rpmat.hwcap & HWCAP_ARM_VFP) + strcpy(un.machine, "armv6hl"); + } +# endif /* arm*-linux */ + +# if defined(__linux__) && defined(__riscv__) + if (rstreq(un.machine, "riscv")) { + if (sizeof(long) == 4) + strcpy(un.machine, "riscv32"); + else if (sizeof(long) == 8) + strcpy(un.machine, "riscv64"); + else if (sizeof(long) == 16) + strcpy(un.machine, "riscv128"); + } +# endif /* riscv */ + # if defined(__GNUC__) && defined(__alpha__) { unsigned long amask, implver; @@ -1147,17 +1286,17 @@ static void defaultMachine(const char ** arch, /* the uname() result goes through the arch_canon table */ canon = lookupInCanonTable(un.machine, - tables[RPM_MACHTABLE_INSTARCH].canons, - tables[RPM_MACHTABLE_INSTARCH].canonsLength); + ctx->tables[RPM_MACHTABLE_INSTARCH].canons, + ctx->tables[RPM_MACHTABLE_INSTARCH].canonsLength); if (canon) rstrlcpy(un.machine, canon->short_name, sizeof(un.machine)); canon = lookupInCanonTable(un.sysname, - tables[RPM_MACHTABLE_INSTOS].canons, - tables[RPM_MACHTABLE_INSTOS].canonsLength); + ctx->tables[RPM_MACHTABLE_INSTOS].canons, + ctx->tables[RPM_MACHTABLE_INSTOS].canonsLength); if (canon) rstrlcpy(un.sysname, canon->short_name, sizeof(un.sysname)); - gotDefaults = 1; + ctx->machDefaults = 1; break; } @@ -1166,34 +1305,30 @@ static void defaultMachine(const char ** arch, } static -const char * rpmGetVarArch(int var, const char * arch) +const char * rpmGetVarArch(rpmrcCtx ctx, int var, const char * arch) { const struct rpmvarValue * next; - if (arch == NULL) arch = current[ARCH]; + if (arch == NULL) arch = ctx->current[ARCH]; if (arch) { - next = &values[var]; + next = &ctx->values[var]; while (next) { if (next->arch && rstreq(next->arch, arch)) return next->value; next = next->next; } } - next = values + var; + next = ctx->values + var; while (next && next->arch) next = next->next; return next ? next->value : NULL; } -static const char *rpmGetVar(int var) -{ - return rpmGetVarArch(var, NULL); -} - -static void rpmSetVarArch(int var, const char * val, const char * arch) +static void rpmSetVarArch(rpmrcCtx ctx, + int var, const char * val, const char * arch) { - struct rpmvarValue * next = values + var; + struct rpmvarValue * next = ctx->values + var; if (next->value) { if (arch) { @@ -1225,39 +1360,23 @@ static void rpmSetVarArch(int var, const char * val, const char * arch) next->arch = (arch ? xstrdup(arch) : NULL); } -static void rpmSetTables(int archTable, int osTable) +static void rpmSetTables(rpmrcCtx ctx, int archTable, int osTable) { const char * arch, * os; - defaultMachine(&arch, &os); + defaultMachine(ctx, &arch, &os); - if (currTables[ARCH] != archTable) { - currTables[ARCH] = archTable; - rebuildCompatTables(ARCH, arch); + if (ctx->currTables[ARCH] != archTable) { + ctx->currTables[ARCH] = archTable; + rebuildCompatTables(ctx, ARCH, arch); } - if (currTables[OS] != osTable) { - currTables[OS] = osTable; - rebuildCompatTables(OS, os); + if (ctx->currTables[OS] != osTable) { + ctx->currTables[OS] = osTable; + rebuildCompatTables(ctx, OS, os); } } -int rpmMachineScore(int type, const char * name) -{ - machEquivInfo info = NULL; - if (name) - info = machEquivSearch(&tables[type].equiv, name); - return info ? info->score : 0; -} - -int rpmIsKnownArch(const char *name) -{ - canonEntry canon = lookupInCanonTable(name, - tables[RPM_MACHTABLE_INSTARCH].canons, - tables[RPM_MACHTABLE_INSTARCH].canonsLength); - return (canon != NULL || rstreq(name, "noarch")); -} - /** \ingroup rpmrc * Set current arch/os names. * NULL as argument is set to the default value (munged uname()) @@ -1265,43 +1384,44 @@ int rpmIsKnownArch(const char *name) * @deprecated Use addMacro to set _target_* macros. * @todo Eliminate * + * @param ctx rpmrc context * @param arch arch name (or NULL) * @param os os name (or NULL) * */ -static void rpmSetMachine(const char * arch, const char * os) +static void rpmSetMachine(rpmrcCtx ctx, const char * arch, const char * os) { const char * host_cpu, * host_os; - defaultMachine(&host_cpu, &host_os); + defaultMachine(ctx, &host_cpu, &host_os); if (arch == NULL) { arch = host_cpu; - if (tables[currTables[ARCH]].hasTranslate) + if (ctx->tables[ctx->currTables[ARCH]].hasTranslate) arch = lookupInDefaultTable(arch, - tables[currTables[ARCH]].defaults, - tables[currTables[ARCH]].defaultsLength); + ctx->tables[ctx->currTables[ARCH]].defaults, + ctx->tables[ctx->currTables[ARCH]].defaultsLength); } if (arch == NULL) return; /* XXX can't happen */ if (os == NULL) { os = host_os; - if (tables[currTables[OS]].hasTranslate) + if (ctx->tables[ctx->currTables[OS]].hasTranslate) os = lookupInDefaultTable(os, - tables[currTables[OS]].defaults, - tables[currTables[OS]].defaultsLength); + ctx->tables[ctx->currTables[OS]].defaults, + ctx->tables[ctx->currTables[OS]].defaultsLength); } if (os == NULL) return; /* XXX can't happen */ - if (!current[ARCH] || !rstreq(arch, current[ARCH])) { - current[ARCH] = _free(current[ARCH]); - current[ARCH] = xstrdup(arch); - rebuildCompatTables(ARCH, host_cpu); + if (!ctx->current[ARCH] || !rstreq(arch, ctx->current[ARCH])) { + ctx->current[ARCH] = _free(ctx->current[ARCH]); + ctx->current[ARCH] = xstrdup(arch); + rebuildCompatTables(ctx, ARCH, host_cpu); } - if (!current[OS] || !rstreq(os, current[OS])) { + if (!ctx->current[OS] || !rstreq(os, ctx->current[OS])) { char * t = xstrdup(os); - current[OS] = _free(current[OS]); + ctx->current[OS] = _free(ctx->current[OS]); /* * XXX Capitalizing the 'L' is needed to insure that old * XXX os-from-uname (e.g. "Linux") is compatible with the new @@ -1312,79 +1432,49 @@ static void rpmSetMachine(const char * arch, const char * os) */ if (rstreq(t, "linux")) *t = 'L'; - current[OS] = t; + ctx->current[OS] = t; - rebuildCompatTables(OS, host_os); + rebuildCompatTables(ctx, OS, host_os); } } -static void rebuildCompatTables(int type, const char * name) +static void rebuildCompatTables(rpmrcCtx ctx, int type, const char * name) { - machFindEquivs(&tables[currTables[type]].cache, - &tables[currTables[type]].equiv, + machFindEquivs(&ctx->tables[ctx->currTables[type]].cache, + &ctx->tables[ctx->currTables[type]].equiv, name); } -static void getMachineInfo(int type, const char ** name, - int * num) +static void getMachineInfo(rpmrcCtx ctx, + int type, const char ** name, int * num) { canonEntry canon; - int which = currTables[type]; + int which = ctx->currTables[type]; /* use the normal canon tables, even if we're looking up build stuff */ if (which >= 2) which -= 2; - canon = lookupInCanonTable(current[type], - tables[which].canons, - tables[which].canonsLength); + canon = lookupInCanonTable(ctx->current[type], + ctx->tables[which].canons, + ctx->tables[which].canonsLength); if (canon) { if (num) *num = canon->num; if (name) *name = canon->short_name; } else { if (num) *num = 255; - if (name) *name = current[type]; + if (name) *name = ctx->current[type]; - if (tables[currTables[type]].hasCanon) { - rpmlog(RPMLOG_WARNING, _("Unknown system: %s\n"), current[type]); + if (ctx->tables[ctx->currTables[type]].hasCanon) { + rpmlog(RPMLOG_WARNING, _("Unknown system: %s\n"), + ctx->current[type]); rpmlog(RPMLOG_WARNING, _("Please contact %s\n"), PACKAGE_BUGREPORT); } } } -void rpmGetArchInfo(const char ** name, int * num) -{ - getMachineInfo(ARCH, name, num); -} - -int rpmGetArchColor(const char *arch) -{ - const char *color; - char *e; - int color_i; - - arch = lookupInDefaultTable(arch, - tables[currTables[ARCH]].defaults, - tables[currTables[ARCH]].defaultsLength); - color = rpmGetVarArch(RPMVAR_ARCHCOLOR, arch); - if (color == NULL) { - return -1; - } - - color_i = strtol(color, &e, 10); - if (!(e && *e == '\0')) { - return -1; - } - - return color_i; -} - -void rpmGetOsInfo(const char ** name, int * num) -{ - getMachineInfo(OS, name, num); -} - -static void rpmRebuildTargetVars(const char ** target, const char ** canontarget) +static void rpmRebuildTargetVars(rpmrcCtx ctx, + const char ** target, const char ** canontarget) { char *ca = NULL, *co = NULL, *ct = NULL; @@ -1392,9 +1482,9 @@ static void rpmRebuildTargetVars(const char ** target, const char ** canontarget /* Rebuild the compat table to recalculate the current target arch. */ - rpmSetMachine(NULL, NULL); - rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS); - rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS); + rpmSetMachine(ctx, NULL, NULL); + rpmSetTables(ctx, RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS); + rpmSetTables(ctx, RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS); if (target && *target) { char *c; @@ -1419,16 +1509,16 @@ static void rpmRebuildTargetVars(const char ** target, const char ** canontarget const char *a = NULL; const char *o = NULL; /* Set build target from rpm arch and os */ - rpmGetArchInfo(&a, NULL); + getMachineInfo(ctx, ARCH, &a, NULL); ca = (a) ? xstrdup(a) : NULL; - rpmGetOsInfo(&o, NULL); + getMachineInfo(ctx, OS, &o, NULL); co = (o) ? xstrdup(o) : NULL; } /* If still not set, Set target arch/os from default uname(2) values */ if (ca == NULL) { const char *a = NULL; - defaultMachine(&a, NULL); + defaultMachine(ctx, &a, NULL); ca = xstrdup(a ? a : "(arch)"); } for (x = 0; ca[x] != '\0'; x++) @@ -1436,7 +1526,7 @@ static void rpmRebuildTargetVars(const char ** target, const char ** canontarget if (co == NULL) { const char *o = NULL; - defaultMachine(NULL, &o); + defaultMachine(ctx, NULL, &o); co = xstrdup(o ? o : "(os)"); } for (x = 0; co[x] != '\0'; x++) @@ -1451,19 +1541,19 @@ static void rpmRebuildTargetVars(const char ** target, const char ** canontarget * XXX All this macro pokery/jiggery could be achieved by doing a delayed * rpmInitMacros(NULL, PER-PLATFORM-MACRO-FILE-NAMES); */ - delMacro(NULL, "_target"); - addMacro(NULL, "_target", NULL, ct, RMIL_RPMRC); - delMacro(NULL, "_target_cpu"); - addMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC); - delMacro(NULL, "_target_os"); - addMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC); + rpmPopMacro(NULL, "_target"); + rpmPushMacro(NULL, "_target", NULL, ct, RMIL_RPMRC); + rpmPopMacro(NULL, "_target_cpu"); + rpmPushMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC); + rpmPopMacro(NULL, "_target_os"); + rpmPushMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC); /* * XXX Make sure that per-arch optflags is initialized correctly. */ - { const char *optflags = rpmGetVarArch(RPMVAR_OPTFLAGS, ca); + { const char *optflags = rpmGetVarArch(ctx, RPMVAR_OPTFLAGS, ca); if (optflags != NULL) { - delMacro(NULL, "optflags"); - addMacro(NULL, "optflags", NULL, optflags, RMIL_RPMRC); + rpmPopMacro(NULL, "optflags"); + rpmPushMacro(NULL, "optflags", NULL, optflags, RMIL_RPMRC); } } @@ -1475,97 +1565,20 @@ static void rpmRebuildTargetVars(const char ** target, const char ** canontarget free(co); } -void rpmFreeRpmrc(void) -{ - int i, j, k; - - if (platpat) - for (i = 0; i < nplatpat; i++) - platpat[i] = _free(platpat[i]); - platpat = _free(platpat); - nplatpat = 0; - - for (i = 0; i < RPM_MACHTABLE_COUNT; i++) { - tableType t; - t = tables + i; - if (t->equiv.list) { - for (j = 0; j < t->equiv.count; j++) - t->equiv.list[j].name = _free(t->equiv.list[j].name); - t->equiv.list = _free(t->equiv.list); - t->equiv.count = 0; - } - if (t->cache.cache) { - for (j = 0; j < t->cache.size; j++) { - machCacheEntry e; - e = t->cache.cache + j; - if (e == NULL) - continue; - e->name = _free(e->name); - if (e->equivs) { - for (k = 0; k < e->count; k++) - e->equivs[k] = _free(e->equivs[k]); - e->equivs = _free(e->equivs); - } - } - t->cache.cache = _free(t->cache.cache); - t->cache.size = 0; - } - if (t->defaults) { - for (j = 0; j < t->defaultsLength; j++) { - t->defaults[j].name = _free(t->defaults[j].name); - t->defaults[j].defName = _free(t->defaults[j].defName); - } - t->defaults = _free(t->defaults); - t->defaultsLength = 0; - } - if (t->canons) { - for (j = 0; j < t->canonsLength; j++) { - t->canons[j].name = _free(t->canons[j].name); - t->canons[j].short_name = _free(t->canons[j].short_name); - } - t->canons = _free(t->canons); - t->canonsLength = 0; - } - } - - for (i = 0; i < RPMVAR_NUM; i++) { - struct rpmvarValue * vp; - while ((vp = values[i].next) != NULL) { - values[i].next = vp->next; - vp->value = _free(vp->value); - vp->arch = _free(vp->arch); - vp = _free(vp); - } - values[i].value = _free(values[i].value); - values[i].arch = _free(values[i].arch); - } - current[OS] = _free(current[OS]); - current[ARCH] = _free(current[ARCH]); - defaultsInitialized = 0; -/* FIX: platpat/current may be NULL */ - - /* XXX doesn't really belong here but... */ - rpmFreeCrypto(); -#ifdef WITH_LUA - rpmLuaFree(); -#endif - - return; -} - /** \ingroup rpmrc * Read rpmrc (and macro) configuration file(s). + * @param ctx rpmrc context * @param rcfiles colon separated files to read (NULL uses default) * @return RPMRC_OK on success */ -static rpmRC rpmReadRC(const char * rcfiles) +static rpmRC rpmReadRC(rpmrcCtx ctx, const char * rcfiles) { ARGV_t p, globs = NULL, files = NULL; rpmRC rc = RPMRC_FAIL; - if (!defaultsInitialized) { + if (!ctx->pathDefaults) { setDefaults(); - defaultsInitialized = 1; + ctx->pathDefaults = 1; } if (rcfiles == NULL) @@ -1592,29 +1605,47 @@ static rpmRC rpmReadRC(const char * rcfiles) goto exit; break; } else { - rc = doReadRC(*p); + rc = doReadRC(ctx, *p); } } rc = RPMRC_OK; - rpmSetMachine(NULL, NULL); /* XXX WTFO? Why bother? */ + rpmSetMachine(ctx, NULL, NULL); /* XXX WTFO? Why bother? */ exit: argvFree(files); return rc; } +static void register_atexit(void) +{ + if (atexit(rpmAtExit) != 0) + rpmlog(RPMLOG_WARNING, _("failed to register exit handler")); +} + +/* External interfaces */ + int rpmReadConfigFiles(const char * file, const char * target) { + static pthread_once_t atexit_registered = PTHREAD_ONCE_INIT; + int rc = -1; /* assume failure */ + rpmrcCtx ctx = rpmrcCtxAcquire(1); + + pthread_once(&atexit_registered, register_atexit); + /* Force preloading of dlopen()'ed libraries in case we go chrooting */ - (void) gethostbyname("localhost"); - (void) rpmInitCrypto(); + if (rpmugInit()) + goto exit; + + if (rpmInitCrypto()) + goto exit; /* Preset target macros */ /* FIX: target can be NULL */ - rpmRebuildTargetVars(&target, NULL); + rpmRebuildTargetVars(ctx, &target, NULL); /* Read the files */ - if (rpmReadRC(file)) return -1; + if (rpmReadRC(ctx, file)) + goto exit; if (macrofiles != NULL) { char *mf = rpmGetPath(macrofiles, NULL); @@ -1623,12 +1654,12 @@ int rpmReadConfigFiles(const char * file, const char * target) } /* Reset target macros */ - rpmRebuildTargetVars(&target, NULL); + rpmRebuildTargetVars(ctx, &target, NULL); /* Finally set target platform */ { char *cpu = rpmExpand("%{_target_cpu}", NULL); char *os = rpmExpand("%{_target_os}", NULL); - rpmSetMachine(cpu, os); + rpmSetMachine(ctx, cpu, os); free(cpu); free(os); } @@ -1637,12 +1668,93 @@ int rpmReadConfigFiles(const char * file, const char * target) /* Force Lua state initialization */ rpmLuaInit(); #endif + rc = 0; - return 0; +exit: + rpmrcCtxRelease(ctx); + return rc; +} + +void rpmFreeRpmrc(void) +{ + rpmrcCtx ctx = rpmrcCtxAcquire(1); + int i, j, k; + + ctx->platpat = argvFree(ctx->platpat); + + for (i = 0; i < RPM_MACHTABLE_COUNT; i++) { + tableType t; + t = ctx->tables + i; + if (t->equiv.list) { + for (j = 0; j < t->equiv.count; j++) + t->equiv.list[j].name = _free(t->equiv.list[j].name); + t->equiv.list = _free(t->equiv.list); + t->equiv.count = 0; + } + if (t->cache.cache) { + for (j = 0; j < t->cache.size; j++) { + machCacheEntry e; + e = t->cache.cache + j; + if (e == NULL) + continue; + e->name = _free(e->name); + if (e->equivs) { + for (k = 0; k < e->count; k++) + e->equivs[k] = _free(e->equivs[k]); + e->equivs = _free(e->equivs); + } + } + t->cache.cache = _free(t->cache.cache); + t->cache.size = 0; + } + if (t->defaults) { + for (j = 0; j < t->defaultsLength; j++) { + t->defaults[j].name = _free(t->defaults[j].name); + t->defaults[j].defName = _free(t->defaults[j].defName); + } + t->defaults = _free(t->defaults); + t->defaultsLength = 0; + } + if (t->canons) { + for (j = 0; j < t->canonsLength; j++) { + t->canons[j].name = _free(t->canons[j].name); + t->canons[j].short_name = _free(t->canons[j].short_name); + } + t->canons = _free(t->canons); + t->canonsLength = 0; + } + } + + for (i = 0; i < RPMVAR_NUM; i++) { + struct rpmvarValue * vp; + while ((vp = ctx->values[i].next) != NULL) { + ctx->values[i].next = vp->next; + vp->value = _free(vp->value); + vp->arch = _free(vp->arch); + vp = _free(vp); + } + ctx->values[i].value = _free(ctx->values[i].value); + ctx->values[i].arch = _free(ctx->values[i].arch); + } + ctx->current[OS] = _free(ctx->current[OS]); + ctx->current[ARCH] = _free(ctx->current[ARCH]); + ctx->machDefaults = 0; + ctx->pathDefaults = 0; + + /* XXX doesn't really belong here but... */ + rpmFreeCrypto(); +#ifdef WITH_LUA + rpmLuaFree(); +#endif + + rpmrcCtxRelease(ctx); + return; } int rpmShowRC(FILE * fp) { + /* Write-context necessary as this calls rpmSetTables(), ugh */ + rpmrcCtx ctx = rpmrcCtxAcquire(1); const struct rpmOption *opt; rpmds ds = NULL; int i; @@ -1650,43 +1762,43 @@ int rpmShowRC(FILE * fp) /* the caller may set the build arch which should be printed here */ fprintf(fp, "ARCHITECTURE AND OS:\n"); - fprintf(fp, "build arch : %s\n", current[ARCH]); + fprintf(fp, "build arch : %s\n", ctx->current[ARCH]); fprintf(fp, "compatible build archs:"); - equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv; + equivTable = &ctx->tables[RPM_MACHTABLE_BUILDARCH].equiv; for (i = 0; i < equivTable->count; i++) fprintf(fp," %s", equivTable->list[i].name); fprintf(fp, "\n"); - fprintf(fp, "build os : %s\n", current[OS]); + fprintf(fp, "build os : %s\n", ctx->current[OS]); fprintf(fp, "compatible build os's :"); - equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv; + equivTable = &ctx->tables[RPM_MACHTABLE_BUILDOS].equiv; for (i = 0; i < equivTable->count; i++) fprintf(fp," %s", equivTable->list[i].name); fprintf(fp, "\n"); - rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS); - rpmSetMachine(NULL, NULL); /* XXX WTFO? Why bother? */ + rpmSetTables(ctx, RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS); + rpmSetMachine(ctx, NULL, NULL); /* XXX WTFO? Why bother? */ - fprintf(fp, "install arch : %s\n", current[ARCH]); - fprintf(fp, "install os : %s\n", current[OS]); + fprintf(fp, "install arch : %s\n", ctx->current[ARCH]); + fprintf(fp, "install os : %s\n", ctx->current[OS]); fprintf(fp, "compatible archs :"); - equivTable = &tables[RPM_MACHTABLE_INSTARCH].equiv; + equivTable = &ctx->tables[RPM_MACHTABLE_INSTARCH].equiv; for (i = 0; i < equivTable->count; i++) fprintf(fp," %s", equivTable->list[i].name); fprintf(fp, "\n"); fprintf(fp, "compatible os's :"); - equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv; + equivTable = &ctx->tables[RPM_MACHTABLE_INSTOS].equiv; for (i = 0; i < equivTable->count; i++) fprintf(fp," %s", equivTable->list[i].name); fprintf(fp, "\n"); fprintf(fp, "\nRPMRC VALUES:\n"); for (i = 0, opt = optionTable; i < optionTableSize; i++, opt++) { - const char *s = rpmGetVar(opt->var); + const char *s = rpmGetVarArch(ctx, opt->var, NULL); if (s != NULL || rpmIsVerbose()) fprintf(fp, "%-21s : %s\n", opt->name, s ? s : "(not set)"); } @@ -1703,7 +1815,74 @@ int rpmShowRC(FILE * fp) ds = rpmdsFree(ds); fprintf(fp, "\n"); + fprintf(fp, "Macro path: %s\n", macrofiles); + fprintf(fp, "\n"); + rpmDumpMacroTable(NULL, fp); + /* XXX: Move this earlier eventually... */ + rpmrcCtxRelease(ctx); + return 0; } + +int rpmMachineScore(int type, const char * name) +{ + int score = 0; + if (name) { + rpmrcCtx ctx = rpmrcCtxAcquire(0); + machEquivInfo info = machEquivSearch(&ctx->tables[type].equiv, name); + if (info) + score = info->score; + rpmrcCtxRelease(ctx); + } + return score; +} + +int rpmIsKnownArch(const char *name) +{ + rpmrcCtx ctx = rpmrcCtxAcquire(0); + canonEntry canon = lookupInCanonTable(name, + ctx->tables[RPM_MACHTABLE_INSTARCH].canons, + ctx->tables[RPM_MACHTABLE_INSTARCH].canonsLength); + int known = (canon != NULL || rstreq(name, "noarch")); + rpmrcCtxRelease(ctx); + return known; +} + +void rpmGetArchInfo(const char ** name, int * num) +{ + rpmrcCtx ctx = rpmrcCtxAcquire(0); + getMachineInfo(ctx, ARCH, name, num); + rpmrcCtxRelease(ctx); +} + +int rpmGetArchColor(const char *arch) +{ + rpmrcCtx ctx = rpmrcCtxAcquire(0); + const char *color; + char *e; + int color_i = -1; /* assume failure */ + + arch = lookupInDefaultTable(arch, + ctx->tables[ctx->currTables[ARCH]].defaults, + ctx->tables[ctx->currTables[ARCH]].defaultsLength); + color = rpmGetVarArch(ctx, RPMVAR_ARCHCOLOR, arch); + if (color) { + color_i = strtol(color, &e, 10); + if (!(e && *e == '\0')) { + color_i = -1; + } + } + rpmrcCtxRelease(ctx); + + return color_i; +} + +void rpmGetOsInfo(const char ** name, int * num) +{ + rpmrcCtx ctx = rpmrcCtxAcquire(0); + getMachineInfo(ctx, OS, name, num); + rpmrcCtxRelease(ctx); +} + |