• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

lib/rpmrc.c

Go to the documentation of this file.
00001 #include "system.h"
00002 
00003 #include <stdarg.h>
00004 
00005 #if defined(HAVE_SYS_SYSTEMCFG_H)
00006 #include <sys/systemcfg.h>
00007 #else
00008 #define __power_pc() 0
00009 #endif
00010 
00011 #define _MIRE_INTERNAL
00012 #include <rpmio_internal.h> /* for rpmioSlurp() */
00013 #include <rpmlua.h>
00014 #include <rpmluaext.h>
00015 #include <rpmmacro.h>
00016 #include <rpmcli.h>
00017 #include <rpmds.h>
00018 
00019 #include "debug.h"
00020 
00021 /*@access miRE@*/
00022 
00023 /*@unchecked@*/ /*@null@*/
00024 static const char * configTarget = NULL;
00025 
00026 /*@observer@*/ /*@unchecked@*/
00027 static const char * platform = SYSCONFIGDIR "/platform";
00028 /*@only@*/ /*@relnull@*/ /*@unchecked@*/
00029 void * platpat = NULL;
00030 /*@unchecked@*/
00031 int nplatpat = 0;
00032 
00033 typedef /*@owned@*/ const char * cptr_t;
00034 
00035 typedef struct machCacheEntry_s {
00036     const char * name;
00037     int count;
00038     cptr_t * equivs;
00039     int visited;
00040 } * machCacheEntry;
00041 
00042 typedef struct machCache_s {
00043     machCacheEntry cache;
00044     int size;
00045 } * machCache;
00046 
00047 typedef struct machEquivInfo_s {
00048     const char * name;
00049     int score;
00050 } * machEquivInfo;
00051 
00052 typedef struct machEquivTable_s {
00053     int count;
00054     machEquivInfo list;
00055 } * machEquivTable;
00056 
00057 typedef struct defaultEntry_s {
00058 /*@owned@*/ /*@null@*/ const char * name;
00059 /*@owned@*/ /*@null@*/ const char * defName;
00060 } * defaultEntry;
00061 
00062 typedef struct canonEntry_s {
00063 /*@owned@*/ const char * name;
00064 /*@owned@*/ const char * short_name;
00065     short num;
00066 } * canonEntry;
00067 
00068 /* tags are 'key'canon, 'key'translate, 'key'compat
00069  *
00070  * for giggles, 'key'_canon, 'key'_compat, and 'key'_canon will also work
00071  */
00072 typedef struct tableType_s {
00073 /*@observer@*/ const char * const key;
00074     const int hasCanon;
00075     const int hasTranslate;
00076     struct machEquivTable_s equiv;
00077     struct machCache_s cache;
00078     defaultEntry defaults;
00079     canonEntry canons;
00080     int defaultsLength;
00081     int canonsLength;
00082 } * tableType;
00083 
00084 /*@-fullinitblock@*/
00085 /*@unchecked@*/
00086 static struct tableType_s tables[RPM_MACHTABLE_COUNT] = {
00087     { "arch", 1, 0 },
00088     { "os", 1, 0 },
00089     { "buildarch", 0, 1 },
00090     { "buildos", 0, 1 }
00091 };
00092 /*@=fullinitblock@*/
00093 
00094 #define OS      0
00095 #define ARCH    1
00096 
00097 /*@unchecked@*/
00098 static cptr_t current[2];
00099 
00100 /*@unchecked@*/
00101 static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH };
00102 
00103 /*@unchecked@*/
00104 static int defaultsInitialized = 0;
00105 
00106 /* prototypes */
00107 static void rpmRebuildTargetVars(/*@null@*/ const char **target, /*@null@*/ const char ** canontarget)
00108         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00109         /*@modifies *canontarget, rpmGlobalMacroContext,
00110                 fileSystem, internalState @*/;
00111 
00112 static /*@observer@*/ /*@null@*/ machCacheEntry
00113 machCacheFindEntry(const machCache cache, const char * key)
00114         /*@*/
00115 {
00116     int i;
00117 
00118     for (i = 0; i < cache->size; i++)
00119         if (!strcmp(cache->cache[i].name, key)) return cache->cache + i;
00120 
00121     return NULL;
00122 }
00123 
00124 static void machAddEquiv(machEquivTable table, const char * name,
00125                            int distance)
00126         /*@modifies table->list, table->count @*/
00127 {
00128     machEquivInfo equiv;
00129 
00130     {   int i;
00131         equiv = NULL;
00132         for (i = 0; i < table->count; i++) {
00133             if (xstrcasecmp(table->list[i].name, name))
00134                 continue;
00135             equiv = table->list + i;
00136             break;
00137         }
00138     }
00139 
00140     if (!equiv) {
00141         if (table->count)
00142             table->list = xrealloc(table->list, (table->count + 1)
00143                                     * sizeof(*table->list));
00144         else
00145             table->list = xmalloc(sizeof(*table->list));
00146 
00147         table->list[table->count].name = xstrdup(name);
00148         table->list[table->count++].score = distance;
00149     }
00150 }
00151 
00152 static void machCacheEntryVisit(machCache cache,
00153                 machEquivTable table, const char * name, int distance)
00154         /*@modifies table->list, table->count @*/
00155 {
00156     machCacheEntry entry;
00157     int i;
00158 
00159     entry = machCacheFindEntry(cache, name);
00160     if (!entry || entry->visited) return;
00161 
00162     entry->visited = 1;
00163 
00164     for (i = 0; i < entry->count; i++) {
00165         machAddEquiv(table, entry->equivs[i], distance);
00166     }
00167 
00168     for (i = 0; i < entry->count; i++) {
00169         machCacheEntryVisit(cache, table, entry->equivs[i], distance + 1);
00170     }
00171 }
00172 
00173 static void rebuildCompatTables(int type, const char * name)
00174         /*@globals tables, internalState @*/
00175         /*@modifies tables, internalState @*/
00176 {
00177     machCache cache = &tables[currTables[type]].cache;
00178     machEquivTable table = &tables[currTables[type]].equiv;
00179     const char * key = name;
00180     int i;
00181 
00182     for (i = 0; i < cache->size; i++)
00183         cache->cache[i].visited = 0;
00184 
00185     while (table->count > 0) {
00186         --table->count;
00187         table->list[table->count].name = _free(table->list[table->count].name);
00188     }
00189     table->count = 0;
00190     table->list = _free(table->list);
00191 
00192     /*
00193      *  We have a general graph built using strings instead of pointers.
00194      *  Yuck. We have to start at a point at traverse it, remembering how
00195      *  far away everything is.
00196      */
00197     /*@-nullstate@*/    /* FIX: table->list may be NULL. */
00198     machAddEquiv(table, key, 1);
00199     machCacheEntryVisit(cache, table, key, 2);
00200     return;
00201     /*@=nullstate@*/
00202 }
00203 
00204 static /*@null@*/ canonEntry lookupInCanonTable(const char * name,
00205                 const canonEntry table, int tableLen)
00206         /*@*/
00207 {
00208     while (tableLen) {
00209         tableLen--;
00210         if (strcmp(name, table[tableLen].name))
00211             continue;
00212         /*@-immediatetrans -retalias@*/
00213         return &(table[tableLen]);
00214         /*@=immediatetrans =retalias@*/
00215     }
00216 
00217     return NULL;
00218 }
00219 
00220 static /*@observer@*/ /*@null@*/
00221 const char * lookupInDefaultTable(const char * name,
00222                 const defaultEntry table, int tableLen)
00223         /*@*/
00224 {
00225     while (tableLen) {
00226         tableLen--;
00227         if (table[tableLen].name && !strcmp(name, table[tableLen].name))
00228             return table[tableLen].defName;
00229     }
00230 
00231     return name;
00232 }
00233 
00234 static void addMacroDefault(const char * macroname,
00235                 const char * val, /*@null@*/ const char * body)
00236         /*@globals rpmGlobalMacroContext, internalState @*/
00237         /*@modifies rpmGlobalMacroContext, internalState @*/
00238 {
00239     if (body == NULL)
00240         body = val;
00241     addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
00242 }
00243 
00244 static void setPathDefault(const char * macroname, const char * subdir)
00245         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00246         /*@modifies rpmGlobalMacroContext, internalState @*/
00247 {
00248     if (macroname != NULL) {
00249 #define _TOPDIRMACRO    "%{_topdir}/"
00250         char *body = alloca(sizeof(_TOPDIRMACRO) + strlen(subdir));
00251         strcpy(body, _TOPDIRMACRO);
00252         strcat(body, subdir);
00253         addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
00254 #undef _TOPDIRMACRO
00255     }
00256 }
00257 
00258 /*@observer@*/ /*@unchecked@*/
00259 static const char * ___build_pre = "\n\
00260 RPM_SOURCE_DIR=\"%{_sourcedir}\"\n\
00261 RPM_BUILD_DIR=\"%{_builddir}\"\n\
00262 RPM_OPT_FLAGS=\"%{optflags}\"\n\
00263 RPM_ARCH=\"%{_arch}\"\n\
00264 RPM_OS=\"%{_os}\"\n\
00265 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\n\
00266 RPM_DOC_DIR=\"%{_docdir}\"\n\
00267 export RPM_DOC_DIR\n\
00268 RPM_PACKAGE_NAME=\"%{name}\"\n\
00269 RPM_PACKAGE_VERSION=\"%{version}\"\n\
00270 RPM_PACKAGE_RELEASE=\"%{release}\"\n\
00271 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\n\
00272 %{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\n\
00273 export RPM_BUILD_ROOT\n}\
00274 ";
00275 
00276 static void setDefaults(void)
00277         /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
00278         /*@modifies rpmGlobalMacroContext, internalState @*/
00279 {
00280 
00281     addMacro(NULL, "_usr", NULL, USRPREFIX, RMIL_DEFAULT);
00282     addMacro(NULL, "_var", NULL, VARPREFIX, RMIL_DEFAULT);
00283     addMacro(NULL, "_prefix", NULL, "%{_usr}", RMIL_DEFAULT);
00284 
00285     addMacro(NULL, "___build_pre", NULL, ___build_pre, RMIL_DEFAULT);
00286 
00287     addMacroDefault("_topdir",
00288                 "%{_usr}/src/rpm",      NULL);
00289     addMacroDefault("_tmppath",
00290                 "%{_var}/tmp",          NULL);
00291     addMacroDefault("_dbpath",
00292                 "%{_var}/lib/rpm",      NULL);
00293     addMacroDefault("_defaultdocdir",
00294                 "%{_usr}/share/doc",    NULL);
00295 
00296     addMacroDefault("_rpmfilename",
00297         "%%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm",NULL);
00298 
00299     addMacroDefault("optflags",
00300                 "-O2 -g",                       NULL);
00301     addMacroDefault("sigtype",
00302                 "none",                 NULL);
00303     addMacroDefault("_buildshell",
00304                 "/bin/sh",              NULL);
00305 
00306     setPathDefault("_builddir", "BUILD");
00307     setPathDefault("_rpmdir",   "RPMS");
00308     setPathDefault("_srcrpmdir",        "SRPMS");
00309     setPathDefault("_sourcedir",        "SOURCES");
00310     setPathDefault("_specdir",  "SPECS");
00311 
00312 }
00313 
00314 typedef struct cpu_vendor_os_gnu {
00315 /*@owned@*/
00316     const char * str;
00317 /*@observer@*/
00318     const char * cpu;
00319 /*@observer@*/
00320     const char * vendor;
00321 /*@observer@*/
00322     const char * os;
00323 /*@observer@*/
00324     const char * gnu;
00325 } * CVOG_t;
00326 
00329 static int parseCVOG(const char * str, CVOG_t *cvogp)
00330         /*@modifies *cvogp @*/
00331 {
00332     CVOG_t cvog = xcalloc(1, sizeof(*cvog));
00333     char * p, * pe;
00334 
00335     cvog->str = p = xstrdup(str);
00336     pe = p + strlen(p);
00337     while (pe-- > p && isspace(*pe))
00338         *pe = '\0';
00339 
00340     cvog->cpu = p;
00341     cvog->vendor = "unknown";
00342     cvog->os = "unknown";
00343     cvog->gnu = "";
00344     while (*p && !(*p == '-' || isspace(*p)))
00345             p++;
00346     if (*p != '\0') *p++ = '\0';
00347 
00348     cvog->vendor = p;
00349     while (*p && !(*p == '-' || isspace(*p)))
00350         p++;
00351     if (*p != '-') {
00352         if (*p != '\0') *p++ = '\0';
00353         cvog->os = cvog->vendor;
00354         cvog->vendor = "unknown";
00355     } else {
00356         if (*p != '\0') *p++ = '\0';
00357 
00358         cvog->os = p;
00359         while (*p && !(*p == '-' || isspace(*p)))
00360             p++;
00361         if (*p == '-') {
00362             *p++ = '\0';
00363 
00364             cvog->gnu = p;
00365             while (*p && !(*p == '-' || isspace(*p)))
00366                 p++;
00367         }
00368         if (*p != '\0') *p++ = '\0';
00369     }
00370 
00371     if (cvogp)
00372         *cvogp = cvog;
00373     else {
00374         cvog->str = _free(cvog->str);
00375         cvog = _free(cvog);
00376     }
00377     return 0;
00378 }
00379 
00386 /*@-onlytrans@*/        /* XXX miRE array, not refcounted. */
00387 /*@null@*/
00388 static void * mireFreeAll(/*@only@*/ /*@null@*/ miRE mire, int nre)
00389         /*@modifies mire@*/
00390 {
00391     if (mire != NULL) {
00392         int i;
00393         for (i = 0; i < nre; i++)
00394             (void) mireClean(mire + i);
00395         mire = _free(mire);
00396     }
00397     return NULL;
00398 }
00399 /*@=onlytrans@*/
00400 
00409 /*@-onlytrans@*/        /* XXX miRE array, not refcounted. */
00410 /*@null@*/
00411 static int mireAppend(rpmMireMode mode, int tag, const char * pattern,
00412                 miRE * mi_rep, int * mi_nrep)
00413         /*@modifies *mi_rep, *mi_nrep @*/
00414 {
00415     miRE mire;
00416 
00417     mire = (*mi_rep);
00418 /*@-refcounttrans@*/
00419     mire = xrealloc(mire, ((*mi_nrep) + 1) * sizeof(*mire));
00420 /*@=refcounttrans@*/
00421     (*mi_rep) = mire;
00422     mire += (*mi_nrep);
00423     (*mi_nrep)++;
00424     memset(mire, 0, sizeof(*mire));
00425     mire->mode = mode;
00426     mire->tag = tag;
00427     return mireRegcomp(mire, pattern);
00428 }
00429 /*@=onlytrans@*/
00430 
00436 /*@-onlytrans@*/        /* XXX miRE array, not refcounted. */
00437 static rpmRC rpmPlatform(const char * platform)
00438         /*@globals nplatpat, platpat,
00439                 rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00440         /*@modifies nplatpat, platpat,
00441                 rpmGlobalMacroContext, fileSystem, internalState @*/
00442 {
00443     CVOG_t cvog = NULL;
00444     uint8_t * b = NULL;
00445     ssize_t blen = 0;
00446     int init_platform = 0;
00447     miRE mi_re = NULL;
00448     int mi_nre = 0;
00449     char * p, * pe;
00450     rpmRC rc;
00451     int xx;
00452 
00453     rc = rpmioSlurp(platform, &b, &blen);
00454 
00455     if (rc || b == NULL || blen <= 0) {
00456         rc = RPMRC_FAIL;
00457         goto exit;
00458     }
00459 
00460     p = (char *)b;
00461     for (pe = p; p && *p; p = pe) {
00462         pe = strchr(p, '\n');
00463         if (pe)
00464             *pe++ = '\0';
00465 
00466         while (*p && xisspace(*p))
00467             p++;
00468         if (*p == '\0' || *p == '#')
00469             continue;
00470 
00471         if (init_platform) {
00472             char * t = p + strlen(p);
00473             while (--t > p && xisspace(*t))
00474                 *t = '\0';
00475             if (t > p)
00476                 xx = mireAppend(RPMMIRE_REGEX, 0, p, &mi_re, &mi_nre);
00477             continue;
00478         }
00479 
00480         if (!parseCVOG(p, &cvog) && cvog != NULL) {
00481             addMacro(NULL, "_host_cpu", NULL, cvog->cpu, -1);
00482             addMacro(NULL, "_host_vendor", NULL, cvog->vendor, -1);
00483             addMacro(NULL, "_host_os", NULL, cvog->os, -1);
00484         }
00485 
00486 #if defined(RPM_VENDOR_OPENPKG) /* explicit-platform */
00487         /* do not use vendor and GNU attribution */
00488         p = rpmExpand("%{_host_cpu}-%{_host_os}", NULL);
00489 #else
00490         p = rpmExpand("%{_host_cpu}-%{_host_vendor}-%{_host_os}",
00491                 (cvog && *cvog->gnu ? "-" : NULL),
00492                 (cvog ? cvog->gnu : NULL), NULL);
00493 #endif
00494         xx = mireAppend(RPMMIRE_STRCMP, 0, p, &mi_re, &mi_nre);
00495         p = _free(p);
00496         
00497         init_platform++;
00498     }
00499     rc = (init_platform ? RPMRC_OK : RPMRC_FAIL);
00500 
00501 exit:
00502     if (cvog) {
00503         cvog->str = _free(cvog->str);
00504         cvog = _free(cvog);
00505     }
00506 /*@-modobserver@*/
00507     b = _free(b);
00508 /*@=modobserver@*/
00509     if (rc == RPMRC_OK) {
00510         platpat = mireFreeAll(platpat, nplatpat);
00511         platpat = mi_re;
00512         nplatpat = mi_nre;
00513     }
00514     return rc;
00515 }
00516 /*@=onlytrans@*/
00517 
00518 /*@-onlytrans@*/        /* XXX miRE array, not refcounted. */
00519 int rpmPlatformScore(const char * platform, void * mi_re, int mi_nre)
00520 {
00521     miRE mire;
00522     int i;
00523 
00524     if (mi_re == NULL) {
00525         mi_re = platpat;
00526         mi_nre = nplatpat;
00527     }
00528 
00529     if ((mire = mi_re) != NULL)
00530     for (i = 0; i < mi_nre; i++) {
00531         if (!mireRegexec(mire + i, platform))
00532             return (i + 1);
00533     }
00534     return 0;
00535 }
00536 /*@=onlytrans@*/
00537 
00540 static void defaultMachine(/*@out@*/ const char ** arch,
00541                 /*@out@*/ const char ** os)
00542         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00543         /*@modifies *arch, *os, rpmGlobalMacroContext, fileSystem, internalState @*/
00544 {
00545 #if defined(RPM_VENDOR_OPENPKG) /* larger-utsname */
00546     /* utsname fields on some platforms (like HP-UX) are very small
00547        (just about 8 characters). This is too small for OpenPKG, so cheat! */
00548     static struct utsname un_real;
00549     static struct {
00550         char sysname[32];
00551         char nodename[32];
00552         char release[32];
00553         char version[32];
00554         char machine[32];
00555     } un;
00556 #else
00557     static struct utsname un;
00558 #endif
00559     static int gotDefaults = 0;
00560     int rc;
00561 
00562     while (!gotDefaults) {
00563         CVOG_t cvog = NULL;
00564 #if defined(RPM_VENDOR_OPENPKG) /* larger-utsname */
00565         const char *cp;
00566 #endif
00567 #if defined(RPM_VENDOR_OPENPKG) /* larger-utsname */
00568         /* utsname fields on some platforms (like HP-UX) are very small
00569            (just about 8 characters). This is too small for OpenPKG, so cheat! */
00570         rc = uname(&un_real);
00571         strncpy(un.sysname,  un_real.sysname,  sizeof(un.sysname));  un.sysname [sizeof(un.sysname) -1] = '\0';
00572         strncpy(un.nodename, un_real.nodename, sizeof(un.nodename)); un.nodename[sizeof(un.nodename)-1] = '\0';
00573         strncpy(un.release,  un_real.release,  sizeof(un.release));  un.release [sizeof(un.release) -1] = '\0';
00574         strncpy(un.version,  un_real.version,  sizeof(un.version));  un.version [sizeof(un.version) -1] = '\0';
00575         strncpy(un.machine,  un_real.machine,  sizeof(un.machine));  un.machine [sizeof(un.machine) -1] = '\0';
00576 #else
00577         rc = uname(&un);
00578 #endif
00579         if (rc < 0) return;
00580 
00581 #if defined(RPM_VENDOR_OPENPKG) /* platform-major-minor-only */
00582     /* Reduce the platform version to major and minor version numbers */
00583     {
00584         char *cp;
00585         char *cpR;
00586         int n;
00587         cpR = un.release;
00588         if ((n = strcspn(cpR, "0123456789")) > 0)
00589             cpR += n;
00590         if ((n = strspn(cpR, "0123456789.")) > 0) {
00591             /* terminate after "N.N.N...." prefix */
00592             cpR[n] = '\0';
00593             /* shorten to "N.N" if longer */
00594             if ((cp = strchr(cpR, '.')) != NULL) {
00595                 if ((cp = strchr(cp+1, '.')) != NULL)
00596                     *cp = '\0';
00597             }
00598             strcat(un.sysname, cpR);
00599         }
00600         /* fix up machine hardware name containing white-space as it
00601            happens to be on Power Macs running MacOS X */
00602         if (!strncmp(un.machine, "Power Macintosh", 15))
00603             sprintf(un.machine, "powerpc");
00604     }
00605 #endif
00606 
00607         if (!strncmp(un.machine, "Power Macintosh", 15)) {
00608             sprintf(un.machine, "ppc");
00609         }
00610 
00611 #if defined(RPM_VENDOR_OPENPKG) /* explicit-platform */
00612         /* allow the path to the "platforms" file be overridden under run-time */
00613         cp = rpmExpand("%{?__platform}", NULL);
00614         if (cp == NULL || cp[0] == '\0')
00615             cp = platform;
00616         if (rpmPlatform(cp) == RPMRC_OK) {
00617 #else
00618         if (rpmPlatform(platform) == RPMRC_OK) {
00619 #endif
00620             const char * s;
00621             gotDefaults = 1;
00622             s = rpmExpand("%{?_host_cpu}", NULL);
00623             if (s && *s != '\0') {
00624                 strncpy(un.machine, s, sizeof(un.machine));
00625                 un.machine[sizeof(un.machine)-1] = '\0';
00626             }
00627             s = _free(s);
00628             s = rpmExpand("%{?_host_os}", NULL);
00629             if (s && *s != '\0') {
00630                 strncpy(un.sysname, s, sizeof(un.sysname));
00631                 un.sysname[sizeof(un.sysname)-1] = '\0';
00632             }
00633             s = _free(s);
00634         }
00635 
00636 #if defined(RPM_VENDOR_OPENPKG) /* explicit-platform */
00637         /* cleanup after above processing */
00638         if (cp != NULL && cp != platform)
00639             cp = _free(cp);
00640 #endif
00641 
00642         if (configTarget && !parseCVOG(configTarget, &cvog) && cvog != NULL) {
00643             gotDefaults = 1;
00644             if (cvog->cpu && cvog->cpu[0] != '\0') {
00645                 strncpy(un.machine, cvog->cpu, sizeof(un.machine));
00646                 un.machine[sizeof(un.machine)-1] = '\0';
00647             }
00648             if (cvog->os && cvog->os[0] != '\0') {
00649                 strncpy(un.sysname, cvog->os, sizeof(un.sysname));
00650                 un.sysname[sizeof(un.sysname)-1] = '\0';
00651             }
00652             cvog->str = _free(cvog->str);
00653             cvog = _free(cvog);
00654         }
00655         if (gotDefaults)
00656             break;
00657         gotDefaults = 1;
00658         break;
00659     }
00660 
00661     if (arch) *arch = un.machine;
00662     if (os) *os = un.sysname;
00663 }
00664 
00665 void rpmSetTables(int archTable, int osTable)
00666         /*@globals currTables @*/
00667         /*@modifies currTables @*/
00668 {
00669     const char * arch, * os;
00670 
00671     defaultMachine(&arch, &os);
00672 
00673     if (currTables[ARCH] != archTable) {
00674         currTables[ARCH] = archTable;
00675         rebuildCompatTables(ARCH, arch);
00676     }
00677 
00678     if (currTables[OS] != osTable) {
00679         currTables[OS] = osTable;
00680         rebuildCompatTables(OS, os);
00681     }
00682 }
00683 
00684 static void rpmSetMachine(const char * arch, const char * os)
00685         /*@globals current, rpmGlobalMacroContext, h_errno,
00686                 fileSystem, internalState @*/
00687         /*@modifies current, rpmGlobalMacroContext,
00688                 fileSystem, internalState @*/
00689 {
00690     if (arch == NULL) {
00691 /*@i@*/ defaultMachine(&arch, NULL);
00692         if (tables[currTables[ARCH]].hasTranslate)
00693             arch = lookupInDefaultTable(arch,
00694                             tables[currTables[ARCH]].defaults,
00695                             tables[currTables[ARCH]].defaultsLength);
00696     }
00697 assert(arch != NULL);
00698 
00699     if (os == NULL) {
00700 /*@i@*/ defaultMachine(NULL, &os);
00701         if (tables[currTables[OS]].hasTranslate)
00702             os = lookupInDefaultTable(os,
00703                             tables[currTables[OS]].defaults,
00704                             tables[currTables[OS]].defaultsLength);
00705     }
00706 assert(os != NULL);
00707 
00708 
00709     if (!current[ARCH] || strcmp(arch, current[ARCH])) {
00710         current[ARCH] = _free(current[ARCH]);
00711         current[ARCH] = xstrdup(arch);
00712         rebuildCompatTables(ARCH, arch);
00713     }
00714 
00715     if (!current[OS] || strcmp(os, current[OS])) {
00716         char * t = xstrdup(os);
00717         current[OS] = _free(current[OS]);
00718         if (!strcmp(t, "linux"))
00719             *t = 'L';
00720         current[OS] = t;
00721         rebuildCompatTables(OS, os);
00722     }
00723 }
00724 
00725 static void getMachineInfo(int type, /*@null@*/ /*@out@*/ const char ** name,
00726                         /*@null@*/ /*@out@*/int * num)
00727         /*@modifies *name, *num @*/
00728 {
00729     canonEntry canon;
00730     int which = currTables[type];
00731 
00732     /* use the normal canon tables, even if we're looking up build stuff */
00733     if (which >= 2) which -= 2;
00734 
00735     canon = lookupInCanonTable(current[type],
00736                                tables[which].canons,
00737                                tables[which].canonsLength);
00738 
00739     if (canon) {
00740         if (num) *num = canon->num;
00741         if (name) *name = canon->short_name;
00742     } else {
00743         if (num) *num = 255;
00744         if (name) *name = current[type];
00745     }
00746 }
00747 
00748 static void rpmRebuildTargetVars(const char ** target, const char ** canontarget)
00749 {
00750 
00751     char *ca = NULL, *co = NULL, *ct = NULL;
00752     int x;
00753 
00754     /* Rebuild the compat table to recalculate the current target arch.  */
00755 
00756     rpmSetMachine(NULL, NULL);
00757     rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS);
00758     rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
00759 
00760     if (target && *target) {
00761         char *c;
00762         /* Set arch and os from specified build target */
00763         ca = xstrdup(*target);
00764         if ((c = strchr(ca, '-')) != NULL) {
00765             *c++ = '\0';
00766             
00767             if ((co = strrchr(c, '-')) == NULL) {
00768                 co = c;
00769             } else {
00770                 if (!xstrcasecmp(co, "-gnu"))
00771                     *co = '\0';
00772                 if ((co = strrchr(c, '-')) == NULL)
00773                     co = c;
00774                 else
00775                     co++;
00776             }
00777             if (co != NULL) co = xstrdup(co);
00778         }
00779     } else {
00780         const char *a = NULL;
00781         const char *o = NULL;
00782         /* Set build target from rpm arch and os */
00783         getMachineInfo(ARCH, &a, NULL);
00784         ca = (a) ? xstrdup(a) : NULL;
00785         getMachineInfo(OS, &o, NULL);
00786         co = (o) ? xstrdup(o) : NULL;
00787     }
00788 
00789     /* If still not set, Set target arch/os from default uname(2) values */
00790     if (ca == NULL) {
00791         const char *a = NULL;
00792         defaultMachine(&a, NULL);
00793         ca = (a) ? xstrdup(a) : NULL;
00794     }
00795     if (ca != NULL)
00796     for (x = 0; ca[x] != '\0'; x++)
00797         ca[x] = xtolower(ca[x]);
00798 
00799     if (co == NULL) {
00800         const char *o = NULL;
00801         defaultMachine(NULL, &o);
00802         co = (o) ? xstrdup(o) : NULL;
00803     }
00804     if (co != NULL)
00805     for (x = 0; co[x] != '\0'; x++)
00806         co[x] = xtolower(co[x]);
00807 
00808     /* XXX For now, set canonical target to arch-os */
00809     if (ct == NULL) {
00810         ct = xmalloc(strlen(ca) + sizeof("-") + strlen(co));
00811         sprintf(ct, "%s-%s", ca, co);
00812     }
00813 
00814 /*
00815  * XXX All this macro pokery/jiggery could be achieved by doing a delayed
00816  *      rpmInitMacros(NULL, PER-PLATFORM-MACRO-FILE-NAMES);
00817  */
00818     delMacro(NULL, "_target");
00819     addMacro(NULL, "_target", NULL, ct, RMIL_RPMRC);
00820     delMacro(NULL, "_target_cpu");
00821     addMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC);
00822     delMacro(NULL, "_target_os");
00823     addMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC);
00824 
00825     if (canontarget)
00826         *canontarget = ct;
00827     else
00828         ct = _free(ct);
00829     ca = _free(ca);
00830     /*@-usereleased@*/
00831     co = _free(co);
00832     /*@=usereleased@*/
00833 }
00834 
00835 void rpmFreeRpmrc(void)
00836         /*@globals current, tables, defaultsInitialized @*/
00837         /*@modifies current, tables, defaultsInitialized @*/
00838 {
00839     int i, j, k;
00840 
00841     platpat = mireFreeAll(platpat, nplatpat);
00842     nplatpat = 0;
00843 
00844     for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
00845         tableType t;
00846         t = tables + i;
00847         if (t->equiv.list) {
00848             for (j = 0; j < t->equiv.count; j++)
00849                 t->equiv.list[j].name = _free(t->equiv.list[j].name);
00850             t->equiv.list = _free(t->equiv.list);
00851             t->equiv.count = 0;
00852         }
00853         if (t->cache.cache) {
00854             for (j = 0; j < t->cache.size; j++) {
00855                 machCacheEntry e;
00856                 e = t->cache.cache + j;
00857                 if (e == NULL)
00858                     /*@innercontinue@*/ continue;
00859                 e->name = _free(e->name);
00860                 if (e->equivs) {
00861                     for (k = 0; k < e->count; k++)
00862                         e->equivs[k] = _free(e->equivs[k]);
00863                     e->equivs = _free(e->equivs);
00864                 }
00865             }
00866             t->cache.cache = _free(t->cache.cache);
00867             t->cache.size = 0;
00868         }
00869         if (t->defaults) {
00870             for (j = 0; j < t->defaultsLength; j++) {
00871                 t->defaults[j].name = _free(t->defaults[j].name);
00872                 t->defaults[j].defName = _free(t->defaults[j].defName);
00873             }
00874             t->defaults = _free(t->defaults);
00875             t->defaultsLength = 0;
00876         }
00877         if (t->canons) {
00878             for (j = 0; j < t->canonsLength; j++) {
00879                 t->canons[j].name = _free(t->canons[j].name);
00880                 t->canons[j].short_name = _free(t->canons[j].short_name);
00881             }
00882             t->canons = _free(t->canons);
00883             t->canonsLength = 0;
00884         }
00885     }
00886 
00887     current[OS] = _free(current[OS]);
00888     current[ARCH] = _free(current[ARCH]);
00889     defaultsInitialized = 0;
00890 /*@-globstate -nullstate@*/ /* FIX: platpat/current may be NULL */
00891     return;
00892 /*@=globstate =nullstate@*/
00893 }
00894 
00899 static int rpmReadRC(void)
00900         /*@globals defaultsInitialized, rpmMacrofiles,
00901                 rpmGlobalMacroContext, rpmCLIMacroContext, h_errno,
00902                 fileSystem, internalState @*/
00903         /*@modifies defaultsInitialized, rpmGlobalMacroContext,
00904                 fileSystem, internalState @*/
00905 {
00906     int rc = 0;
00907 
00908     if (!defaultsInitialized) {
00909         setDefaults();
00910         defaultsInitialized = 1;
00911     }
00912 
00913     /* Read macro files. */
00914     {   const char *mfpath = rpmExpand(rpmMacrofiles, NULL);
00915             
00916         if (mfpath != NULL) {
00917             rpmInitMacros(NULL, mfpath);
00918             mfpath = _free(mfpath);
00919         }
00920     }
00921 
00922     return rc;
00923 }
00924 
00925 int rpmReadConfigFiles(/*@unused@*/ const char * file, const char * target)
00926         /*@globals configTarget @*/
00927         /*@modifies configTarget @*/
00928 {
00929     mode_t mode = 0022;
00930 
00931     /* Reset umask to its default umask(2) value. */
00932     mode = umask(mode);
00933 
00934     configTarget = target;
00935 
00936     /* Preset target macros */
00937     /*@-nullstate@*/    /* FIX: target can be NULL */
00938     rpmRebuildTargetVars(&target, NULL);
00939 
00940     /* Read the files */
00941 /*@-globs@*/
00942     if (rpmReadRC()) return -1;
00943 /*@=globs@*/
00944 
00945     /* Reset target macros */
00946     rpmRebuildTargetVars(&target, NULL);
00947     /*@=nullstate@*/
00948 
00949     /* Finally set target platform */
00950     {   const char *cpu = rpmExpand("%{_target_cpu}", NULL);
00951         const char *os = rpmExpand("%{_target_os}", NULL);
00952         rpmSetMachine(cpu, os);
00953         cpu = _free(cpu);
00954         os = _free(os);
00955     }
00956     configTarget = NULL;
00957 
00958     /* Force Lua state initialization */
00959 #ifdef WITH_LUA
00960     (void)rpmluaGetPrintBuffer(NULL);
00961 #if defined(RPM_VENDOR_OPENPKG) /* rpm-lua-extensions-based-on-rpm-lib-functionality */
00962     (void)rpmluaextActivate(rpmluaGetGlobalState());
00963 #endif /* RPM_VENDOR_OPENPKG */
00964 #endif
00965 
00966     return 0;
00967 }
00968 
00969 int rpmShowRC(FILE * fp)
00970 {
00971     rpmds ds = NULL;
00972     int i;
00973     machEquivTable equivTable;
00974     int xx;
00975 
00976     /* the caller may set the build arch which should be printed here */
00977     fprintf(fp, "ARCHITECTURE AND OS:\n");
00978     fprintf(fp, "build arch            : %s\n", current[ARCH]);
00979 
00980     fprintf(fp, "compatible build archs:");
00981     equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv;
00982     for (i = 0; i < equivTable->count; i++)
00983         fprintf(fp," %s", equivTable->list[i].name);
00984     fprintf(fp, "\n");
00985 
00986     fprintf(fp, "build os              : %s\n", current[OS]);
00987 
00988     fprintf(fp, "compatible build os's :");
00989     equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv;
00990     for (i = 0; i < equivTable->count; i++)
00991         fprintf(fp," %s", equivTable->list[i].name);
00992     fprintf(fp, "\n");
00993 
00994     fprintf(fp, "install arch          : %s\n", current[ARCH]);
00995     fprintf(fp, "install os            : %s\n", current[OS]);
00996 
00997     fprintf(fp, "compatible archs      :");
00998     equivTable = &tables[RPM_MACHTABLE_INSTARCH].equiv;
00999     for (i = 0; i < equivTable->count; i++)
01000         fprintf(fp," %s", equivTable->list[i].name);
01001     fprintf(fp, "\n");
01002 
01003     fprintf(fp, "compatible os's       :");
01004     equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv;
01005     for (i = 0; i < equivTable->count; i++)
01006         fprintf(fp," %s", equivTable->list[i].name);
01007     fprintf(fp, "\n");
01008 
01009     {   const char * s = rpmExpand("%{?optflags}", NULL);
01010         fprintf(fp, "%-21s : %s\n", "optflags", ((s && *s) ? s : "(not set)"));
01011         s = _free(s);
01012 /*@-globs@*/
01013         s = rpmExpand(rpmMacrofiles, NULL);
01014 /*@=globs@*/
01015         fprintf(fp, "\nMACRO DEFINITIONS:\n");
01016         fprintf(fp, "%-21s : %s\n", "macrofiles", ((s && *s) ? s : "(not set)"));
01017         s = _free(s);
01018     }
01019 
01020     if (rpmIsVerbose()) {
01021         rpmPRCO PRCO = rpmdsNewPRCO(NULL);
01022         xx = rpmdsSysinfo(PRCO, NULL);
01023         ds = rpmdsFromPRCO(PRCO, RPMTAG_PROVIDENAME);
01024         if (ds != NULL) {
01025             fprintf(fp, _("Configured system provides (from /etc/rpm/sysinfo):\n"));
01026             ds = rpmdsInit(ds);
01027             while (rpmdsNext(ds) >= 0) {
01028                 const char * DNEVR = rpmdsDNEVR(ds);
01029                 if (DNEVR != NULL)
01030                     fprintf(fp, "    %s\n", DNEVR+2);
01031             }
01032             ds = rpmdsFree(ds);
01033             fprintf(fp, "\n");
01034         }
01035         PRCO = rpmdsFreePRCO(PRCO);
01036     }
01037 
01038     if (rpmIsVerbose()) {
01039         fprintf(fp, _("Features provided by rpmlib installer:\n"));
01040         xx = rpmdsRpmlib(&ds, NULL);
01041         ds = rpmdsInit(ds);
01042         while (rpmdsNext(ds) >= 0) {
01043             const char * DNEVR = rpmdsDNEVR(ds);
01044             if (DNEVR != NULL)
01045                 fprintf(fp, "    %s\n", DNEVR+2);
01046         }
01047         ds = rpmdsFree(ds);
01048         fprintf(fp, "\n");
01049 
01050         xx = rpmdsCpuinfo(&ds, NULL);
01051         if (ds != NULL) {
01052             fprintf(fp,
01053                 _("Features provided by current cpuinfo (from /proc/cpuinfo):\n"));
01054             ds = rpmdsInit(ds);
01055             while (rpmdsNext(ds) >= 0) {
01056                 const char * DNEVR = rpmdsDNEVR(ds);
01057                 if (DNEVR != NULL)
01058                     fprintf(fp, "    %s\n", DNEVR+2);
01059             }
01060             ds = rpmdsFree(ds);
01061             fprintf(fp, "\n");
01062         }
01063 
01064         xx = rpmdsGetconf(&ds, NULL);
01065         if (ds != NULL) {
01066             fprintf(fp,
01067                 _("Features provided by current getconf:\n"));
01068             ds = rpmdsInit(ds);
01069             while (rpmdsNext(ds) >= 0) {
01070                 const char * DNEVR = rpmdsDNEVR(ds);
01071                 if (DNEVR != NULL)
01072                     fprintf(fp, "    %s\n", DNEVR+2);
01073             }
01074             ds = rpmdsFree(ds);
01075             fprintf(fp, "\n");
01076         }
01077 
01078         xx = rpmdsUname(&ds, NULL);
01079         if (ds != NULL) {
01080             fprintf(fp,
01081                 _("Features provided by current uname:\n"));
01082             ds = rpmdsInit(ds);
01083             while (rpmdsNext(ds) >= 0) {
01084                 const char * DNEVR = rpmdsDNEVR(ds);
01085                 if (DNEVR != NULL)
01086                     fprintf(fp, "    %s\n", DNEVR+2);
01087             }
01088             ds = rpmdsFree(ds);
01089             fprintf(fp, "\n");
01090         }
01091     }
01092 
01093     rpmDumpMacroTable(NULL, fp);
01094 
01095     return 0;
01096 }

Generated on Mon Nov 29 2010 05:18:44 for rpm by  doxygen 1.7.2