Sanitize python object -> tag number exception handling
[platform/upstream/rpm.git] / lib / rpmrc.c
index de29b0c..0818deb 100644 (file)
 
 #include "rpmio/rpmlua.h"
 #include "rpmio/rpmio_internal.h"      /* XXX for rpmioSlurp */
+#include "lib/misc.h"
+#include "lib/rpmliblua.h"
 
 #include "debug.h"
 
-static const char * const defrcfiles = 
-      RPMCONFIGDIR "/rpmrc" 
-  ":" RPMCONFIGDIR "/" RPMCANONVENDOR "/rpmrc"
-  ":" SYSCONFDIR "/rpmrc"
-  ":~/.rpmrc"; 
-
-const char * macrofiles =
-#ifndef MACROFILES
-      RPMCONFIGDIR "/macros"
-  ":" RPMCONFIGDIR "/platform/%{_target}/macros"
-  ":" SYSCONFDIR "/rpm/macros.*"
-  ":" SYSCONFDIR "/rpm/macros"
-  ":" SYSCONFDIR "/rpm/%{_target}/macros"
-  ":~/.rpmmacros";
-#else
-  MACROFILES;
-#endif
+static const char * defrcfiles = NULL;
+const char * macrofiles = NULL;
 
 static const char * const platform = SYSCONFDIR "/rpm/platform";
 static char ** platpat = NULL;
@@ -152,7 +139,7 @@ static struct rpmvarValue values[RPMVAR_NUM];
 static int defaultsInitialized = 0;
 
 /* prototypes */
-static rpmRC doReadRC( FD_t fd, const char * urlfn);
+static rpmRC doReadRC(const char * urlfn);
 
 static void rpmSetVarArch(int var, const char * val,
                const char * arch);
@@ -173,7 +160,7 @@ machCacheFindEntry(const machCache cache, const char * key)
     int i;
 
     for (i = 0; i < cache->size; i++)
-       if (!strcmp(cache->cache[i].name, key)) return cache->cache + i;
+       if (rstreq(cache->cache[i].name, key)) return cache->cache + i;
 
     return NULL;
 }
@@ -350,7 +337,6 @@ static rpmRC addCanon(canonEntry * table, int * tableLen, char * line,
        return RPMRC_FAIL;
     }
 
-       /* LCL: s != NULL here. */
     tnum = strtoul(s, &s1, 10);
     if ((*s1) || (s1 == s) || (tnum == ULONG_MAX)) {
        rpmlog(RPMLOG_ERR, _("Bad arch/os number: %s (%s:%d)\n"), s,
@@ -405,7 +391,7 @@ static canonEntry lookupInCanonTable(const char * name,
 {
     while (tableLen) {
        tableLen--;
-       if (strcmp(name, table[tableLen].name))
+       if (!rstreq(name, table[tableLen].name))
            continue;
        return &(table[tableLen]);
     }
@@ -419,117 +405,53 @@ const char * lookupInDefaultTable(const char * name,
 {
     while (tableLen) {
        tableLen--;
-       if (table[tableLen].name && !strcmp(name, table[tableLen].name))
+       if (table[tableLen].name && rstreq(name, table[tableLen].name))
            return table[tableLen].defName;
     }
 
     return name;
 }
 
-static void addMacroDefault(const char * macroname, const char * val,
-               const char * body)
-{
-    if (body == NULL)
-       body = val;
-    addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
-}
-
-static void setPathDefault(const char * macroname, const char * subdir)
-{
-
-    if (macroname != NULL) {
-#define        _TOPDIRMACRO    "%{_topdir}/"
-       char *body = alloca(sizeof(_TOPDIRMACRO) + strlen(subdir));
-       strcpy(body, _TOPDIRMACRO);
-       strcat(body, subdir);
-       addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
-#undef _TOPDIRMACRO
-    }
-}
-
-static const char * const prescriptenviron = "\n\
-RPM_SOURCE_DIR=\"%{_sourcedir}\"\n\
-RPM_BUILD_DIR=\"%{_builddir}\"\n\
-RPM_OPT_FLAGS=\"%{optflags}\"\n\
-RPM_ARCH=\"%{_arch}\"\n\
-RPM_OS=\"%{_os}\"\n\
-export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\n\
-RPM_DOC_DIR=\"%{_docdir}\"\n\
-export RPM_DOC_DIR\n\
-RPM_PACKAGE_NAME=\"%{name}\"\n\
-RPM_PACKAGE_VERSION=\"%{version}\"\n\
-RPM_PACKAGE_RELEASE=\"%{release}\"\n\
-export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\n\
-%{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\n\
-export RPM_BUILD_ROOT\n}\
-";
-
 static void setDefaults(void)
 {
+    const char *confdir = rpmConfigDir();
+    if (!defrcfiles) {
+       defrcfiles = rstrscat(NULL, confdir, "/rpmrc", ":",
+                               confdir, "/" RPMCANONVENDOR "/rpmrc", ":",
+                               SYSCONFDIR "/rpmrc", ":",
+                               "~/.rpmrc", NULL);
+    }
 
-    addMacro(NULL, "_usr", NULL, "/usr", RMIL_DEFAULT);
-    addMacro(NULL, "_var", NULL, LOCALSTATEDIR, RMIL_DEFAULT);
-
-    addMacro(NULL, "_preScriptEnvironment",NULL, prescriptenviron,RMIL_DEFAULT);
-
-    addMacroDefault("_topdir",
-               "/usr/src/packages",            "%(echo $HOME)/rpmbuild");
-    addMacroDefault("_tmppath",
-               LOCALSTATEDIR "/tmp",           "%{_var}/tmp");
-    addMacroDefault("_dbpath",
-               LOCALSTATEDIR "/lib/rpm",               "%{_var}/lib/rpm");
-    addMacroDefault("_defaultdocdir",
-               "/usr/doc",             "%{_usr}/doc");
-
-    addMacroDefault("_rpmfilename",
-       "%%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm",NULL);
-
-    addMacroDefault("optflags",
-               "-O2",                  NULL);
-    addMacroDefault("sigtype",
-               "none",                 NULL);
-    addMacroDefault("_buildshell",
-               "/bin/sh",              NULL);
-
-    setPathDefault("_builddir",        "BUILD");
-    setPathDefault("_rpmdir",  "RPMS");
-    setPathDefault("_srcrpmdir",       "SRPMS");
-    setPathDefault("_sourcedir",       "SOURCES");
-    setPathDefault("_specdir", "SPECS");
-
+#ifndef MACROFILES
+    if (!macrofiles) {
+       macrofiles = rstrscat(NULL, confdir, "/macros", ":",
+                               confdir, "/platform/%{_target}/macros", ":",
+                               confdir, "/" RPMCANONVENDOR "/macros", ":",
+                               SYSCONFDIR "/rpm/macros.*", ":",
+                               SYSCONFDIR "/rpm/macros", ":",
+                               SYSCONFDIR "/rpm/%{_target}/macros", ":",
+                               "~/.rpmmacros", NULL);
+    }
+#else
+    macrofiles = MACROFILES;
+#endif
 }
 
 /* FIX: se usage inconsistent, W2DO? */
-static rpmRC doReadRC( FD_t fd, const char * urlfn)
+static rpmRC doReadRC(const char * urlfn)
 {
     char *s;
-    char *se, *next;
+    char *se, *next, *buf = NULL, *fn;
     int linenum = 0;
     struct rpmOption searchOption, * option;
-    int rc;
+    rpmRC rc = RPMRC_FAIL;
 
-    /* XXX really need rc = Slurp(fd, const char * filename, char ** buf) */
-  { off_t size = fdSize(fd);
-    size_t nb = (size >= 0 ? size : (8*BUFSIZ - 2));
-    if (nb == 0) {
-       (void) Fclose(fd);
-       return RPMRC_OK;
+    fn = rpmGetPath(urlfn, NULL);
+    if (rpmioSlurp(fn, (uint8_t **) &buf, NULL) || buf == NULL) {
+       goto exit;
     }
-    next = alloca(nb + 2);
-    next[0] = '\0';
-    rc = Fread(next, sizeof(*next), nb, fd);
-    if (Ferror(fd) || (size > 0 && rc != nb)) {        /* XXX Feof(fd) */
-       rpmlog(RPMLOG_ERR, _("Failed to read %s: %s.\n"), urlfn,
-                Fstrerror(fd));
-       rc = RPMRC_FAIL;
-    } else
-       rc = RPMRC_OK;
-    (void) Fclose(fd);
-    if (rc) return rc;
-    next[nb] = '\n';
-    next[nb + 1] = '\0';
-  }
-
+       
+    next = buf;
     while (*next != '\0') {
        linenum++;
 
@@ -557,8 +479,8 @@ static rpmRC doReadRC( FD_t fd, const char * urlfn)
 
        if (*se != ':') {
            rpmlog(RPMLOG_ERR, _("missing ':' (found 0x%02x) at %s:%d\n"),
-                    (unsigned)(0xff & *se), urlfn, linenum);
-           return RPMRC_FAIL;
+                    (unsigned)(0xff & *se), fn, linenum);
+           goto exit;
        }
        *se++ = '\0';   /* terminate keyword or option, point to value */
        while (*se && risspace(*se)) se++;
@@ -570,19 +492,16 @@ static rpmRC doReadRC( FD_t fd, const char * urlfn)
 
        if (option) {   /* For configuration variables  ... */
            const char *arch, *val;
-           char *fn;
 
-           arch = val = fn = NULL;
+           arch = val = NULL;
            if (*se == '\0') {
                rpmlog(RPMLOG_ERR, _("missing argument for %s at %s:%d\n"),
-                     option->name, urlfn, linenum);
-               return RPMRC_FAIL;
+                     option->name, fn, linenum);
+               goto exit;
            }
 
            switch (option->var) {
            case RPMVAR_INCLUDE:
-             { FD_t fdinc;
-
                s = se;
                while (*se && !risspace(*se)) se++;
                if (*se != '\0') *se++ = '\0';
@@ -591,26 +510,14 @@ static rpmRC doReadRC( FD_t fd, const char * urlfn)
                rpmRebuildTargetVars(NULL, NULL);
 #endif
 
-               fn = rpmGetPath(s, NULL);
-               if (fn == NULL || *fn == '\0') {
-                   rpmlog(RPMLOG_ERR, _("%s expansion failed at %s:%d \"%s\"\n"),
-                       option->name, urlfn, linenum, s);
-                   fn = _free(fn);
-                   return RPMRC_FAIL;
-               }
-
-               fdinc = Fopen(fn, "r.fpio");
-               if (fdinc == NULL || Ferror(fdinc)) {
-                   rpmlog(RPMLOG_ERR, _("cannot open %s at %s:%d: %s\n"),
-                       fn, urlfn, linenum, Fstrerror(fdinc));
-                   rc = RPMRC_FAIL;
+               if (doReadRC(s)) {
+                   rpmlog(RPMLOG_ERR, _("cannot open %s at %s:%d: %m\n"),
+                       s, fn, linenum);
+                   goto exit;
                } else {
-                   rc = doReadRC(fdinc, fn);
+                   continue;   /* XXX don't save include value as var/macro */
                }
-               fn = _free(fn);
-               if (rc) return rc;
-               continue;       /* XXX don't save include value as var/macro */
-             } break;
+               break;
            default:
                break;
            }
@@ -621,16 +528,16 @@ static rpmRC doReadRC( FD_t fd, const char * urlfn)
                if (*se == '\0') {
                    rpmlog(RPMLOG_ERR,
                                _("missing architecture for %s at %s:%d\n"),
-                               option->name, urlfn, linenum);
-                   return RPMRC_FAIL;
+                               option->name, fn, linenum);
+                   goto exit;
                }
                *se++ = '\0';
                while (*se && risspace(*se)) se++;
                if (*se == '\0') {
                    rpmlog(RPMLOG_ERR,
                                _("missing argument for %s at %s:%d\n"),
-                               option->name, urlfn, linenum);
-                   return RPMRC_FAIL;
+                               option->name, fn, linenum);
+                   goto exit;
                }
            }
        
@@ -638,7 +545,7 @@ static rpmRC doReadRC( FD_t fd, const char * urlfn)
 
            /* Only add macros if appropriate for this arch */
            if (option->macroize &&
-             (arch == NULL || !strcmp(arch, current[ARCH]))) {
+             (arch == NULL || rstreq(arch, current[ARCH]))) {
                char *n, *name;
                n = name = xmalloc(strlen(option->name)+2);
                if (option->localize)
@@ -657,7 +564,7 @@ static rpmRC doReadRC( FD_t fd, const char * urlfn)
            gotit = 0;
 
            for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
-               if (!strncmp(tables[i].key, s, strlen(tables[i].key)))
+               if (rstreqn(tables[i].key, s, strlen(tables[i].key)))
                    break;
            }
 
@@ -665,35 +572,41 @@ static rpmRC doReadRC( FD_t fd, const char * urlfn)
                const char *rest = s + strlen(tables[i].key);
                if (*rest == '_') rest++;
 
-               if (!strcmp(rest, "compat")) {
-                   if (machCompatCacheAdd(se, urlfn, linenum,
+               if (rstreq(rest, "compat")) {
+                   if (machCompatCacheAdd(se, fn, linenum,
                                                &tables[i].cache))
-                       return 1;
+                       goto exit;
                    gotit = 1;
                } else if (tables[i].hasTranslate &&
-                          !strcmp(rest, "translate")) {
+                          rstreq(rest, "translate")) {
                    if (addDefault(&tables[i].defaults,
                                   &tables[i].defaultsLength,
-                                  se, urlfn, linenum))
-                       return 1;
+                                  se, fn, linenum))
+                       goto exit;
                    gotit = 1;
                } else if (tables[i].hasCanon &&
-                          !strcmp(rest, "canon")) {
+                          rstreq(rest, "canon")) {
                    if (addCanon(&tables[i].canons, &tables[i].canonsLength,
-                                se, urlfn, linenum))
-                       return 1;
+                                se, fn, linenum))
+                       goto exit;
                    gotit = 1;
                }
            }
 
            if (!gotit) {
                rpmlog(RPMLOG_ERR, _("bad option '%s' at %s:%d\n"),
-                           s, urlfn, linenum);
+                           s, fn, linenum);
+               goto exit;
            }
        }
     }
+    rc = RPMRC_OK;
 
-    return RPMRC_OK;
+exit:
+    free(fn);
+    free(buf);
+
+    return rc;
 }
 
 
@@ -905,7 +818,7 @@ static int is_athlon(void)
        for (i=0; i<4; i++)
                vendor[8+i] = (unsigned char) (ecx >>(8*i));
                
-       if (strncmp(vendor, "AuthenticAMD", 12) != 0)  
+       if (!rstreqn(vendor, "AuthenticAMD", 12))  
                return 0;
 
        return 1;
@@ -920,7 +833,7 @@ static int is_pentium3()
     *((unsigned int *)&vendor[0]) = ebx;
     *((unsigned int *)&vendor[4]) = edx;
     *((unsigned int *)&vendor[8]) = ecx;
-    if (strncmp(vendor, "GenuineIntel", 12) != 0)
+    if (!rstreqn(vendor, "GenuineIntel", 12))
        return 0;
     cpuid(1, &eax, &ebx, &ecx, &edx);
     family = (eax >> 8) & 0x0f;
@@ -959,7 +872,7 @@ static int is_pentium4()
     *((unsigned int *)&vendor[0]) = ebx;
     *((unsigned int *)&vendor[4]) = edx;
     *((unsigned int *)&vendor[8]) = ecx;
-    if (strncmp(vendor, "GenuineIntel", 12) != 0)
+    if (!rstreqn(vendor, "GenuineIntel", 12))
        return 0;
     cpuid(1, &eax, &ebx, &ecx, &edx);
     family = (eax >> 8) & 0x0f;
@@ -991,7 +904,7 @@ static int is_geode()
     *((unsigned int *)&vendor[0]) = ebx;
     *((unsigned int *)&vendor[4]) = edx;
     *((unsigned int *)&vendor[8]) = ecx;
-    if (strncmp(vendor, "AuthenticAMD", 12) != 0)  
+    if (!rstreqn(vendor, "AuthenticAMD", 12))
         return 0;
     cpuid(1, &eax, &ebx, &ecx, &edx);
     family = (eax >> 8) & 0x0f;
@@ -1052,19 +965,19 @@ static void defaultMachine(const char ** arch,
         */
        strncpy(un.sysname, "SINIX", sizeof(un.sysname));
 #endif
-       if (!strcmp(un.sysname, "AIX")) {
+       if (rstreq(un.sysname, "AIX")) {
            strcpy(un.machine, __power_pc() ? "ppc" : "rs6000");
            sprintf(un.sysname,"aix%s.%s", un.version, un.release);
        }
-       else if(!strcmp(un.sysname, "Darwin")) { 
+       else if(rstreq(un.sysname, "Darwin")) { 
 #ifdef __ppc__
            strcpy(un.machine, "ppc");
 #else ifdef __i386__
            strcpy(un.machine, "i386");
 #endif 
        }
-       else if (!strcmp(un.sysname, "SunOS")) {
-           if (!strncmp(un.release,"4", 1)) /* SunOS 4.x */ {
+       else if (rstreq(un.sysname, "SunOS")) {
+           if (rstreqn(un.release,"4", 1)) /* SunOS 4.x */ {
                int fd;
                for (fd = 0;
                    (un.release[fd] != 0 && (fd < sizeof(un.release)));
@@ -1084,25 +997,25 @@ static void defaultMachine(const char ** arch,
            /* Solaris on Intel hardware reports i86pc instead of i386
             * (at least on 2.6 and 2.8)
             */
-           if (!strcmp(un.machine, "i86pc"))
+           if (rstreq(un.machine, "i86pc"))
                sprintf(un.machine, "i386");
        }
-       else if (!strcmp(un.sysname, "HP-UX"))
+       else if (rstreq(un.sysname, "HP-UX"))
            /*make un.sysname look like hpux9.05 for example*/
            sprintf(un.sysname, "hpux%s", strpbrk(un.release, "123456789"));
-       else if (!strcmp(un.sysname, "OSF1"))
+       else if (rstreq(un.sysname, "OSF1"))
            /*make un.sysname look like osf3.2 for example*/
            sprintf(un.sysname, "osf%s", strpbrk(un.release, "123456789"));
-       else if (!strncmp(un.sysname, "IP", 2))
+       else if (rstreqn(un.sysname, "IP", 2))
            un.sysname[2] = '\0';
-       else if (!strncmp(un.sysname, "SINIX", 5)) {
+       else if (rstreqn(un.sysname, "SINIX", 5)) {
            sprintf(un.sysname, "sinix%s",un.release);
-           if (!strncmp(un.machine, "RM", 2))
+           if (rstreqn(un.machine, "RM", 2))
                sprintf(un.machine, "mips");
        }
-       else if ((!strncmp(un.machine, "34", 2) ||
-               !strncmp(un.machine, "33", 2)) && \
-               !strncmp(un.release, "4.0", 3))
+       else if ((rstreqn(un.machine, "34", 2) ||
+               rstreqn(un.machine, "33", 2)) && \
+               rstreqn(un.release, "4.0", 3))
        {
            /* we are on ncr-sysv4 */
            char * prelid = NULL;
@@ -1185,7 +1098,7 @@ static void defaultMachine(const char ** arch,
 #      endif   /* hpux */
 
 #      if defined(__linux__) && defined(__sparc__)
-       if (!strcmp(un.machine, "sparc")) {
+       if (rstreq(un.machine, "sparc")) {
            #define PERS_LINUX          0x00000000
            #define PERS_LINUX_32BIT    0x00800000
            #define PERS_LINUX32        0x00000008
@@ -1197,7 +1110,7 @@ static void defaultMachine(const char ** arch,
            if (oldpers != -1) {
                if (personality(PERS_LINUX) != -1) {
                    uname(&un);
-                   if (! strcmp(un.machine, "sparc64")) {
+                   if (rstreq(un.machine, "sparc64")) {
                        strcpy(un.machine, "sparcv9");
                        oldpers = PERS_LINUX32;
                    }
@@ -1280,7 +1193,7 @@ const char * rpmGetVarArch(int var, const char * arch)
     if (arch) {
        next = &values[var];
        while (next) {
-           if (next->arch && !strcmp(next->arch, arch)) return next->value;
+           if (next->arch && rstreq(next->arch, arch)) return next->value;
            next = next->next;
        }
     }
@@ -1303,7 +1216,7 @@ static void rpmSetVarArch(int var, const char * val, const char * arch)
     if (next->value) {
        if (arch) {
            while (next->next) {
-               if (next->arch && !strcmp(next->arch, arch)) break;
+               if (next->arch && rstreq(next->arch, arch)) break;
                next = next->next;
            }
        } else {
@@ -1313,7 +1226,7 @@ static void rpmSetVarArch(int var, const char * val, const char * arch)
            }
        }
 
-       if (next->arch && arch && !strcmp(next->arch, arch)) {
+       if (next->arch && arch && rstreq(next->arch, arch)) {
            next->value = _free(next->value);
            next->arch = _free(next->arch);
        } else if (next->arch || arch) {
@@ -1353,6 +1266,14 @@ int rpmMachineScore(int type, const char * name)
     return (info != NULL ? 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())
@@ -1388,13 +1309,13 @@ static void rpmSetMachine(const char * arch, const char * os)
     }
     if (os == NULL) return;    /* XXX can't happen */
 
-    if (!current[ARCH] || strcmp(arch, current[ARCH])) {
+    if (!current[ARCH] || !rstreq(arch, current[ARCH])) {
        current[ARCH] = _free(current[ARCH]);
        current[ARCH] = xstrdup(arch);
        rebuildCompatTables(ARCH, host_cpu);
     }
 
-    if (!current[OS] || strcmp(os, current[OS])) {
+    if (!current[OS] || !rstreq(os, current[OS])) {
        char * t = xstrdup(os);
        current[OS] = _free(current[OS]);
        /*
@@ -1405,7 +1326,7 @@ static void rpmSetMachine(const char * arch, const char * os)
         * XXX used by rpmInstallPackage->{os,arch}Okay->rpmMachineScore->
         * XXX to verify correct arch/os from headers.
         */
-       if (!strcmp(t, "linux"))
+       if (rstreq(t, "linux"))
            *t = 'L';
        current[OS] = t;
        
@@ -1502,7 +1423,7 @@ static void rpmRebuildTargetVars(const char ** target, const char ** canontarget
     if (ca == NULL) {
        const char *a = NULL;
        defaultMachine(&a, NULL);
-       ca = (a) ? xstrdup(a) : NULL;
+       ca = xstrdup(a ? a : "(arch)");
     }
     for (x = 0; ca[x] != '\0'; x++)
        ca[x] = rtolower(ca[x]);
@@ -1510,7 +1431,7 @@ static void rpmRebuildTargetVars(const char ** target, const char ** canontarget
     if (co == NULL) {
        const char *o = NULL;
        defaultMachine(NULL, &o);
-       co = (o) ? xstrdup(o) : NULL;
+       co = xstrdup(o ? o : "(os)");
     }
     for (x = 0; co[x] != '\0'; x++)
        co[x] = rtolower(co[x]);
@@ -1620,6 +1541,9 @@ void rpmFreeRpmrc(void)
 
     /* XXX doesn't really belong here but... */
     rpmFreeCrypto();
+#ifdef WITH_LUA
+    rpmLuaFree();
+#endif
 
     return;
 }
@@ -1631,8 +1555,8 @@ void rpmFreeRpmrc(void)
  */
 static rpmRC rpmReadRC(const char * rcfiles)
 {
-    char *myrcfiles, *r, *re;
-    int rc;
+    ARGV_t p, globs = NULL, files = NULL;
+    rpmRC rc = RPMRC_FAIL;
 
     if (!defaultsInitialized) {
        setDefaults();
@@ -1642,67 +1566,35 @@ static rpmRC rpmReadRC(const char * rcfiles)
     if (rcfiles == NULL)
        rcfiles = defrcfiles;
 
-    /* Read each file in rcfiles. */
-    rc = RPMRC_OK;
-    for (r = myrcfiles = xstrdup(rcfiles); r && *r != '\0'; r = re) {
-       char fn[4096];
-       FD_t fd;
-
-       /* Get pointer to rest of files */
-       for (re = r; (re = strchr(re, ':')) != NULL; re++) {
-           if (!(re[1] == '/' && re[2] == '/'))
-               break;
-       }
-       if (re && *re == ':')
-           *re++ = '\0';
-       else
-           re = r + strlen(r);
-
-       /* Expand ~/ to $HOME/ */
-       fn[0] = '\0';
-       if (r[0] == '~' && r[1] == '/') {
-           const char * home = getenv("HOME");
-           if (home == NULL) {
-           /* XXX Only /usr/lib/rpm/rpmrc must exist in default rcfiles list */
-               if (rcfiles == defrcfiles && myrcfiles != r)
-                   continue;
-               rpmlog(RPMLOG_ERR, _("Cannot expand %s\n"), r);
-               rc = RPMRC_FAIL;
-               break;
-           }
-           if (strlen(home) > (sizeof(fn) - strlen(r))) {
-               rpmlog(RPMLOG_ERR, _("Cannot read %s, HOME is too large.\n"),
-                               r);
-               rc = RPMRC_FAIL;
-               break;
-           }
-           strcpy(fn, home);
-           r++;
+    /* Expand any globs in rcfiles. Missing files are ok here. */
+    argvSplit(&globs, rcfiles, ":");
+    for (p = globs; *p; p++) {
+       ARGV_t av = NULL;
+       if (rpmGlob(*p, NULL, &av) == 0) {
+           argvAppend(&files, av);
+           argvFree(av);
        }
-       strncat(fn, r, sizeof(fn) - (strlen(fn) + 1));
-       fn[sizeof(fn)-1] = '\0';
-
-       /* Read another rcfile */
-       fd = Fopen(fn, "r.fpio");
-       if (fd == NULL || Ferror(fd)) {
-           /* XXX Only /usr/lib/rpm/rpmrc must exist in default rcfiles list */
-           if (rcfiles == defrcfiles && myrcfiles != r)
+    }
+    argvFree(globs);
+
+    /* Read each file in rcfiles. */
+    for (p = files; p && *p; p++) {
+       /* XXX Only /usr/lib/rpm/rpmrc must exist in default rcfiles list */
+       if (access(*p, R_OK) != 0) {
+           if (rcfiles == defrcfiles && p != files)
                continue;
-           rpmlog(RPMLOG_ERR, _("Unable to open %s for reading: %s.\n"),
-                fn, Fstrerror(fd));
-           rc = RPMRC_FAIL;
+           rpmlog(RPMLOG_ERR, _("Unable to open %s for reading: %m.\n"), *p);
+           goto exit;
            break;
        } else {
-           rc = doReadRC(fd, fn);
+           rc = doReadRC(*p);
        }
-       if (rc) break;
     }
-    myrcfiles = _free(myrcfiles);
-    if (rc)
-       return rc;
-
+    rc = RPMRC_OK;
     rpmSetMachine(NULL, NULL); /* XXX WTFO? Why bother? */
 
+exit:
+    argvFree(files);
     return rc;
 }
 
@@ -1712,10 +1604,9 @@ int rpmReadConfigFiles(const char * file, const char * target)
     /* Reset umask to its default umask(2) value. */
     mode = umask(mode);
 
-    /* Initialize crypto engine as early as possible */
-    if (rpmInitCrypto() < 0) {
-       return -1;
-    }  
+    /* Force preloading of dlopen()'ed libraries in case we go chrooting */
+    (void) gethostbyname("localhost");
+    (void) rpmInitCrypto();
 
     /* Preset target macros */
        /* FIX: target can be NULL */
@@ -1741,9 +1632,9 @@ int rpmReadConfigFiles(const char * file, const char * target)
        os = _free(os);
     }
 
-    /* Force Lua state initialization */
 #ifdef WITH_LUA
-    (void)rpmluaGetPrintBuffer(NULL);
+    /* Force Lua state initialization */
+    rpmLuaInit();
 #endif
 
     return 0;