5 #if defined(__linux__) && defined(__powerpc__)
9 #include <ctype.h> /* XXX for /etc/rpm/platform contents */
11 #if HAVE_SYS_SYSTEMCFG_H
12 #include <sys/systemcfg.h>
14 #define __power_pc() 0
17 #include <rpmio_internal.h>
25 /*@observer@*/ /*@unchecked@*/
26 static const char *defrcfiles = LIBRPMRC_FILENAME ":" VENDORRPMRC_FILENAME
27 ":" SYSCONFDIR "/rpmrc"
30 /*@observer@*/ /*@checked@*/
31 const char * macrofiles =
33 RPMCONFIGDIR "/macros"
34 ":" RPMCONFIGDIR "/%{_target}/macros"
35 ":" SYSCONFDIR "/rpm/macros.*"
36 ":" SYSCONFDIR "/rpm/macros"
37 ":" SYSCONFDIR "/rpm/%{_target}/macros"
43 /*@observer@*/ /*@unchecked@*/
44 static const char * platform = SYSCONFDIR "/rpm/platform";
45 /*@only@*/ /*@relnull@*/ /*@unchecked@*/
46 static const char ** platpat = NULL;
48 static int nplatpat = 0;
50 typedef /*@owned@*/ const char * cptr_t;
52 typedef struct machCacheEntry_s {
59 typedef struct machCache_s {
64 typedef struct machEquivInfo_s {
69 typedef struct machEquivTable_s {
76 /* eventually, this arch will be replaced with a generic condition */
78 /*@only@*/ /*@null@*/ struct rpmvarValue * next;
85 /*@unused@*/ int required;
88 /*@unused@*/ struct rpmOptionValue * value;
91 typedef struct defaultEntry_s {
92 /*@owned@*/ /*@null@*/ const char * name;
93 /*@owned@*/ /*@null@*/ const char * defName;
96 typedef struct canonEntry_s {
97 /*@owned@*/ const char * name;
98 /*@owned@*/ const char * short_name;
102 /* tags are 'key'canon, 'key'translate, 'key'compat
104 * for giggles, 'key'_canon, 'key'_compat, and 'key'_canon will also work
106 typedef struct tableType_s {
107 /*@observer@*/ const char * const key;
109 const int hasTranslate;
110 struct machEquivTable_s equiv;
111 struct machCache_s cache;
112 defaultEntry defaults;
120 static struct tableType_s tables[RPM_MACHTABLE_COUNT] = {
123 { "buildarch", 0, 1 },
127 /* this *must* be kept in alphabetical order */
128 /* The order of the flags is archSpecific, required, macroize, localize */
131 static struct rpmOption optionTable[] = {
132 { "include", RPMVAR_INCLUDE, 0, 1, 0, 2 },
133 { "macrofiles", RPMVAR_MACROFILES, 0, 0, 0, 1 },
134 { "optflags", RPMVAR_OPTFLAGS, 1, 0, 1, 0 },
135 { "provides", RPMVAR_PROVIDES, 0, 0, 0, 0 },
140 static int optionTableSize = sizeof(optionTable) / sizeof(*optionTable);
146 static cptr_t current[2];
149 static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH };
152 static struct rpmvarValue values[RPMVAR_NUM];
155 static int defaultsInitialized = 0;
158 static int doReadRC( /*@killref@*/ FD_t fd, const char * urlfn)
159 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
160 /*@modifies fd, rpmGlobalMacroContext, fileSystem, internalState @*/;
162 static void rpmSetVarArch(int var, const char * val,
163 /*@null@*/ const char * arch)
164 /*@globals values, internalState @*/
165 /*@modifies values, internalState @*/;
167 static void rebuildCompatTables(int type, const char * name)
168 /*@globals internalState @*/
169 /*@modifies internalState @*/;
171 static void rpmRebuildTargetVars(/*@null@*/ const char **target, /*@null@*/ const char ** canontarget)
172 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
173 /*@modifies *canontarget, rpmGlobalMacroContext,
174 fileSystem, internalState @*/;
176 static int optionCompare(const void * a, const void * b)
179 return xstrcasecmp(((struct rpmOption *) a)->name,
180 ((struct rpmOption *) b)->name);
183 static /*@observer@*/ /*@null@*/ machCacheEntry
184 machCacheFindEntry(const machCache cache, const char * key)
189 for (i = 0; i < cache->size; i++)
190 if (!strcmp(cache->cache[i].name, key)) return cache->cache + i;
195 static int machCompatCacheAdd(char * name, const char * fn, int linenum,
197 /*@globals internalState @*/
198 /*@modifies *name, cache->cache, cache->size, internalState @*/
200 machCacheEntry entry = NULL;
206 while (*name && xisspace(*name)) name++;
209 while (*chptr && *chptr != ':') chptr++;
211 rpmError(RPMERR_RPMRC, _("missing second ':' at %s:%d\n"), fn, linenum);
213 } else if (chptr == name) {
214 rpmError(RPMERR_RPMRC, _("missing architecture name at %s:%d\n"), fn,
219 while (*chptr == ':' || xisspace(*chptr)) chptr--;
222 while (*equivs && xisspace(*equivs)) equivs++;
228 entry = machCacheFindEntry(cache, name);
230 for (i = 0; i < entry->count; i++)
231 entry->equivs[i] = _free(entry->equivs[i]);
232 entry->equivs = _free(entry->equivs);
238 cache->cache = xrealloc(cache->cache,
239 (cache->size + 1) * sizeof(*cache->cache));
240 entry = cache->cache + cache->size++;
241 entry->name = xstrdup(name);
246 if (delEntry) return 0;
248 while ((chptr = strtok(equivs, " ")) != NULL) {
250 if (chptr[0] == '\0') /* does strtok() return "" ever?? */
253 entry->equivs = xrealloc(entry->equivs, sizeof(*entry->equivs)
254 * (entry->count + 1));
256 entry->equivs = xmalloc(sizeof(*entry->equivs));
258 entry->equivs[entry->count] = xstrdup(chptr);
265 static /*@observer@*/ /*@null@*/ machEquivInfo
266 machEquivSearch(const machEquivTable table, const char * name)
271 for (i = 0; i < table->count; i++)
272 if (!xstrcasecmp(table->list[i].name, name))
273 return table->list + i;
278 static void machAddEquiv(machEquivTable table, const char * name,
280 /*@modifies table->list, table->count @*/
284 equiv = machEquivSearch(table, name);
287 table->list = xrealloc(table->list, (table->count + 1)
288 * sizeof(*table->list));
290 table->list = xmalloc(sizeof(*table->list));
292 table->list[table->count].name = xstrdup(name);
293 table->list[table->count++].score = distance;
297 static void machCacheEntryVisit(machCache cache,
298 machEquivTable table, const char * name, int distance)
299 /*@modifies table->list, table->count @*/
301 machCacheEntry entry;
304 entry = machCacheFindEntry(cache, name);
305 if (!entry || entry->visited) return;
309 for (i = 0; i < entry->count; i++) {
310 machAddEquiv(table, entry->equivs[i], distance);
313 for (i = 0; i < entry->count; i++) {
314 machCacheEntryVisit(cache, table, entry->equivs[i], distance + 1);
318 static void machFindEquivs(machCache cache, machEquivTable table,
320 /*@modifies cache->cache, table->list, table->count @*/
324 for (i = 0; i < cache->size; i++)
325 cache->cache[i].visited = 0;
327 while (table->count > 0) {
329 table->list[table->count].name = _free(table->list[table->count].name);
332 table->list = _free(table->list);
335 * We have a general graph built using strings instead of pointers.
336 * Yuck. We have to start at a point at traverse it, remembering how
337 * far away everything is.
339 /*@-nullstate@*/ /* FIX: table->list may be NULL. */
340 machAddEquiv(table, key, 1);
341 machCacheEntryVisit(cache, table, key, 2);
346 static int addCanon(canonEntry * table, int * tableLen, char * line,
347 const char * fn, int lineNum)
348 /*@globals internalState @*/
349 /*@modifies *table, *tableLen, *line, internalState @*/
354 const char * tshort_name;
358 /*@-unqualifiedtrans@*/
359 *table = xrealloc(*table, sizeof(**table) * (*tableLen));
360 /*@=unqualifiedtrans@*/
362 t = & ((*table)[*tableLen - 2]);
364 tname = strtok(line, ": \t");
365 tshort_name = strtok(NULL, " \t");
366 s = strtok(NULL, " \t");
367 if (! (tname && tshort_name && s)) {
368 rpmError(RPMERR_RPMRC, _("Incomplete data line at %s:%d\n"),
372 if (strtok(NULL, " \t")) {
373 rpmError(RPMERR_RPMRC, _("Too many args in data line at %s:%d\n"),
378 /*@-nullpass@*/ /* LCL: s != NULL here. */
379 tnum = strtoul(s, &s1, 10);
380 if ((*s1) || (s1 == s) || (tnum == ULONG_MAX)) {
381 rpmError(RPMERR_RPMRC, _("Bad arch/os number: %s (%s:%d)\n"), s,
383 return(RPMERR_RPMRC);
387 t[0].name = xstrdup(tname);
388 t[0].short_name = (tshort_name ? xstrdup(tshort_name) : xstrdup(""));
391 /* From A B C entry */
392 /* Add B B C entry */
393 t[1].name = (tshort_name ? xstrdup(tshort_name) : xstrdup(""));
394 t[1].short_name = (tshort_name ? xstrdup(tshort_name) : xstrdup(""));
400 static int addDefault(defaultEntry * table, int * tableLen, char * line,
401 const char * fn, int lineNum)
402 /*@globals internalState @*/
403 /*@modifies *table, *tableLen, *line, internalState @*/
408 /*@-unqualifiedtrans@*/
409 *table = xrealloc(*table, sizeof(**table) * (*tableLen));
410 /*@=unqualifiedtrans@*/
412 t = & ((*table)[*tableLen - 1]);
415 t->name = strtok(line, ": \t");
416 t->defName = strtok(NULL, " \t");
417 if (! (t->name && t->defName)) {
418 rpmError(RPMERR_RPMRC, _("Incomplete default line at %s:%d\n"),
422 if (strtok(NULL, " \t")) {
423 rpmError(RPMERR_RPMRC, _("Too many args in default line at %s:%d\n"),
428 t->name = xstrdup(t->name);
429 t->defName = (t->defName ? xstrdup(t->defName) : NULL);
435 static /*@null@*/ canonEntry lookupInCanonTable(const char * name,
436 const canonEntry table, int tableLen)
441 if (strcmp(name, table[tableLen].name))
443 /*@-immediatetrans -retalias@*/
444 return &(table[tableLen]);
445 /*@=immediatetrans =retalias@*/
451 static /*@observer@*/ /*@null@*/
452 const char * lookupInDefaultTable(const char * name,
453 const defaultEntry table, int tableLen)
458 if (table[tableLen].name && !strcmp(name, table[tableLen].name))
459 return table[tableLen].defName;
465 static void setVarDefault(int var, const char * macroname, const char * val,
466 /*@null@*/ const char * body)
467 /*@globals rpmGlobalMacroContext, internalState @*/
468 /*@modifies rpmGlobalMacroContext, internalState @*/
470 if (var >= 0) { /* XXX Dying ... */
471 if (rpmGetVar(var)) return;
476 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
479 static void setPathDefault(int var, const char * macroname, const char * subdir)
480 /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
481 /*@modifies rpmGlobalMacroContext, internalState @*/
484 if (var >= 0) { /* XXX Dying ... */
488 if (rpmGetVar(var)) return;
490 topdir = rpmGetPath("%{_topdir}", NULL);
492 fn = alloca(strlen(topdir) + strlen(subdir) + 2);
494 if (fn[strlen(topdir) - 1] != '/')
499 topdir = _free(topdir);
502 if (macroname != NULL) {
503 #define _TOPDIRMACRO "%{_topdir}/"
504 char *body = alloca(sizeof(_TOPDIRMACRO) + strlen(subdir));
505 strcpy(body, _TOPDIRMACRO);
506 strcat(body, subdir);
507 addMacro(NULL, macroname, NULL, body, RMIL_DEFAULT);
512 /*@observer@*/ /*@unchecked@*/
513 static const char * prescriptenviron = "\n\
514 RPM_SOURCE_DIR=\"%{_sourcedir}\"\n\
515 RPM_BUILD_DIR=\"%{_builddir}\"\n\
516 RPM_OPT_FLAGS=\"%{optflags}\"\n\
517 RPM_ARCH=\"%{_arch}\"\n\
519 export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\n\
520 RPM_DOC_DIR=\"%{_docdir}\"\n\
521 export RPM_DOC_DIR\n\
522 RPM_PACKAGE_NAME=\"%{name}\"\n\
523 RPM_PACKAGE_VERSION=\"%{version}\"\n\
524 RPM_PACKAGE_RELEASE=\"%{release}\"\n\
525 export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\n\
526 %{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\n\
527 export RPM_BUILD_ROOT\n}\
530 static void setDefaults(void)
531 /*@globals rpmGlobalMacroContext, h_errno, internalState @*/
532 /*@modifies rpmGlobalMacroContext, internalState @*/
535 addMacro(NULL, "_usr", NULL, "/usr", RMIL_DEFAULT);
536 addMacro(NULL, "_var", NULL, "/var", RMIL_DEFAULT);
538 addMacro(NULL, "_preScriptEnvironment",NULL, prescriptenviron,RMIL_DEFAULT);
540 setVarDefault(-1, "_topdir",
541 "/usr/src/redhat", "%{_usr}/src/redhat");
542 setVarDefault(-1, "_tmppath",
543 "/var/tmp", "%{_var}/tmp");
544 setVarDefault(-1, "_dbpath",
545 "/var/lib/rpm", "%{_var}/lib/rpm");
546 setVarDefault(-1, "_defaultdocdir",
547 "/usr/doc", "%{_usr}/doc");
549 setVarDefault(-1, "_rpmfilename",
550 "%%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm",NULL);
552 setVarDefault(RPMVAR_OPTFLAGS, "optflags",
554 setVarDefault(-1, "sigtype",
556 setVarDefault(-1, "_buildshell",
559 setPathDefault(-1, "_builddir", "BUILD");
560 setPathDefault(-1, "_rpmdir", "RPMS");
561 setPathDefault(-1, "_srcrpmdir", "SRPMS");
562 setPathDefault(-1, "_sourcedir", "SOURCES");
563 setPathDefault(-1, "_specdir", "SPECS");
567 /*@-usedef@*/ /*@ FIX: se usage inconsistent, W2DO? */
568 static int doReadRC( /*@killref@*/ FD_t fd, const char * urlfn)
569 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
570 /*@modifies fd, rpmGlobalMacroContext, fileSystem, internalState @*/
575 struct rpmOption searchOption, * option;
578 /* XXX really need rc = Slurp(fd, const char * filename, char ** buf) */
579 { off_t size = fdSize(fd);
580 size_t nb = (size >= 0 ? size : (8*BUFSIZ - 2));
585 next = alloca(nb + 2);
587 rc = Fread(next, sizeof(*next), nb, fd);
588 if (Ferror(fd) || (size > 0 && rc != nb)) { /* XXX Feof(fd) */
589 rpmError(RPMERR_RPMRC, _("Failed to read %s: %s.\n"), urlfn,
601 while (*next != '\0') {
606 /* Find end-of-line. */
607 while (*se && *se != '\n') se++;
608 if (*se != '\0') *se++ = '\0';
611 /* Trim leading spaces */
612 while (*s && xisspace(*s)) s++;
614 /* We used to allow comments to begin anywhere, but not anymore. */
615 if (*s == '#' || *s == '\0') continue;
617 /* Find end-of-keyword. */
619 while (*se && !xisspace(*se) && *se != ':') se++;
623 while (*se && xisspace(*se) && *se != ':') se++;
627 rpmError(RPMERR_RPMRC, _("missing ':' (found 0x%02x) at %s:%d\n"),
628 (unsigned)(0xff & *se), urlfn, linenum);
631 *se++ = '\0'; /* terminate keyword or option, point to value */
632 while (*se && xisspace(*se)) se++;
634 /* Find keyword in table */
635 searchOption.name = s;
636 option = bsearch(&searchOption, optionTable, optionTableSize,
637 sizeof(optionTable[0]), optionCompare);
639 if (option) { /* For configuration variables ... */
640 const char *arch, *val, *fn;
642 arch = val = fn = NULL;
644 rpmError(RPMERR_RPMRC, _("missing argument for %s at %s:%d\n"),
645 option->name, urlfn, linenum);
649 switch (option->var) {
654 while (*se && !xisspace(*se)) se++;
655 if (*se != '\0') *se++ = '\0';
657 rpmRebuildTargetVars(NULL, NULL);
659 fn = rpmGetPath(s, NULL);
660 if (fn == NULL || *fn == '\0') {
661 rpmError(RPMERR_RPMRC, _("%s expansion failed at %s:%d \"%s\"\n"),
662 option->name, urlfn, linenum, s);
668 fdinc = Fopen(fn, "r.fpio");
669 if (fdinc == NULL || Ferror(fdinc)) {
670 rpmError(RPMERR_RPMRC, _("cannot open %s at %s:%d: %s\n"),
671 fn, urlfn, linenum, Fstrerror(fdinc));
674 rc = doReadRC(fdinc, fn);
678 continue; /* XXX don't save include value as var/macro */
679 } /*@notreached@*/ /*@switchbreak@*/ break;
680 case RPMVAR_MACROFILES:
681 fn = rpmGetPath(se, NULL);
682 if (fn == NULL || *fn == '\0') {
683 rpmError(RPMERR_RPMRC, _("%s expansion failed at %s:%d \"%s\"\n"),
684 option->name, urlfn, linenum, fn);
689 /*@switchbreak@*/ break;
690 case RPMVAR_PROVIDES:
692 s = rpmGetVar(RPMVAR_PROVIDES);
693 if (s == NULL) s = "";
694 fn = t = xmalloc(strlen(s) + strlen(se) + 2);
695 while (*s != '\0') *t++ = *s++;
697 while (*se != '\0') *t++ = *se++;
700 } /*@switchbreak@*/ break;
702 /*@switchbreak@*/ break;
705 if (option->archSpecific) {
707 while (*se && !xisspace(*se)) se++;
709 rpmError(RPMERR_RPMRC,
710 _("missing architecture for %s at %s:%d\n"),
711 option->name, urlfn, linenum);
715 while (*se && xisspace(*se)) se++;
717 rpmError(RPMERR_RPMRC,
718 _("missing argument for %s at %s:%d\n"),
719 option->name, urlfn, linenum);
726 /* Only add macros if appropriate for this arch */
727 if (option->macroize &&
728 (arch == NULL || !strcmp(arch, current[ARCH]))) {
730 n = name = xmalloc(strlen(option->name)+2);
731 if (option->localize)
733 strcpy(n, option->name);
734 addMacro(NULL, name, NULL, val, RMIL_RPMRC);
737 rpmSetVarArch(option->var, val, arch);
740 } else { /* For arch/os compatibilty tables ... */
746 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
747 if (!strncmp(tables[i].key, s, strlen(tables[i].key)))
748 /*@innerbreak@*/ break;
751 if (i < RPM_MACHTABLE_COUNT) {
752 const char *rest = s + strlen(tables[i].key);
753 if (*rest == '_') rest++;
755 if (!strcmp(rest, "compat")) {
756 if (machCompatCacheAdd(se, urlfn, linenum,
760 } else if (tables[i].hasTranslate &&
761 !strcmp(rest, "translate")) {
762 if (addDefault(&tables[i].defaults,
763 &tables[i].defaultsLength,
767 } else if (tables[i].hasCanon &&
768 !strcmp(rest, "canon")) {
769 if (addCanon(&tables[i].canons, &tables[i].canonsLength,
777 rpmError(RPMERR_RPMRC, _("bad option '%s' at %s:%d\n"),
792 static int rpmPlatform(const char * platform)
793 /*@globals nplatpat, platpat,
794 rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
795 /*@modifies nplatpat, platpat,
796 rpmGlobalMacroContext, fileSystem, internalState @*/
798 char *cpu = NULL, *vendor = NULL, *os = NULL, *gnu = NULL;
801 int init_platform = 0;
805 rc = rpmioSlurp(platform, &b, &blen);
807 if (rc || b == NULL || blen <= 0) {
813 for (pe = p; p && *p; p = pe) {
814 pe = strchr(p, '\n');
818 while (*p && isspace(*p))
820 if (*p == '\0' || *p == '#')
824 char * t = p + strlen(p);
826 while (--t > p && isspace(*t))
829 platpat = xrealloc(platpat, (nplatpat + 2) * sizeof(*platpat));
830 /*@-onlyunqglobaltrans@*/
831 platpat[nplatpat] = xstrdup(p);
833 platpat[nplatpat] = NULL;
834 /*@=onlyunqglobaltrans@*/
843 while (*p && !(*p == '-' || isspace(*p)))
845 if (*p != '\0') *p++ = '\0';
848 while (*p && !(*p == '-' || isspace(*p)))
852 if (*p != '\0') *p++ = '\0';
856 if (*p != '\0') *p++ = '\0';
859 while (*p && !(*p == '-' || isspace(*p)))
865 while (*p && !(*p == '-' || isspace(*p)))
868 if (*p != '\0') *p++ = '\0';
872 addMacro(NULL, "_host_cpu", NULL, cpu, -1);
873 addMacro(NULL, "_host_vendor", NULL, vendor, -1);
874 addMacro(NULL, "_host_os", NULL, os, -1);
876 platpat = xrealloc(platpat, (nplatpat + 2) * sizeof(*platpat));
877 /*@-onlyunqglobaltrans@*/
878 platpat[nplatpat] = rpmExpand("%{_host_cpu}-%{_host_vendor}-%{_host_os}", (gnu && *gnu ? "-" : NULL), gnu, NULL);
880 platpat[nplatpat] = NULL;
881 /*@=onlyunqglobaltrans@*/
885 rc = (init_platform ? 0 : -1);
896 # if defined(__linux__) && defined(__i386__)
901 * Generic CPUID function
903 static inline void cpuid(unsigned int op, int *eax, int *ebx, int *ecx, int *edx)
904 /*@modifies *eax, *ebx, *ecx, *edx @*/
907 *eax = *ebx = *ecx = *edx = 0;
912 "movl %%ebx, %%esi \n"
914 : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
919 * CPUID functions returning a single datum
921 static inline unsigned int cpuid_eax(unsigned int op)
924 unsigned int tmp, val;
925 cpuid(op, &val, &tmp, &tmp, &tmp);
929 static inline unsigned int cpuid_ebx(unsigned int op)
932 unsigned int tmp, val;
933 cpuid(op, &tmp, &val, &tmp, &tmp);
937 static inline unsigned int cpuid_ecx(unsigned int op)
940 unsigned int tmp, val;
941 cpuid(op, &tmp, &tmp, &val, &tmp);
945 static inline unsigned int cpuid_edx(unsigned int op)
948 unsigned int tmp, val;
949 cpuid(op, &tmp, &tmp, &tmp, &val);
954 static sigjmp_buf jenv;
956 static inline void model3(int _unused)
957 /*@globals internalState @*/
958 /*@modifies internalState @*/
963 static inline int RPMClass(void)
964 /*@globals internalState @*/
965 /*@modifies internalState @*/
968 unsigned int tfms, junk, cap, capamd;
969 struct sigaction oldsa;
971 sigaction(SIGILL, NULL, &oldsa);
972 signal(SIGILL, model3);
974 if (sigsetjmp(jenv, 1)) {
975 sigaction(SIGILL, &oldsa, NULL);
979 if (cpuid_eax(0x000000000)==0) {
980 sigaction(SIGILL, &oldsa, NULL);
984 cpuid(0x00000001, &tfms, &junk, &junk, &cap);
985 cpuid(0x80000001, &junk, &junk, &junk, &capamd);
989 sigaction(SIGILL, &oldsa, NULL);
995 /* CMOV supported? */
996 if (capamd & (1<<30))
997 return 7; /* 3DNOWEXT supported */
1004 /* should only be called for model 6 CPU's */
1005 static int is_athlon(void)
1008 unsigned int eax, ebx, ecx, edx;
1012 cpuid (0, &eax, &ebx, &ecx, &edx);
1014 /* If you care about space, you can just check ebx, ecx and edx directly
1015 instead of forming a string first and then doing a strcmp */
1016 memset(vendor, 0, sizeof(vendor));
1019 vendor[i] = (unsigned char) (ebx >>(8*i));
1021 vendor[4+i] = (unsigned char) (edx >>(8*i));
1023 vendor[8+i] = (unsigned char) (ecx >>(8*i));
1025 if (strncmp(vendor, "AuthenticAMD", 12) != 0)
1031 static int is_pentium3()
1033 unsigned int eax, ebx, ecx, edx, family, model;
1035 cpuid(0, &eax, &ebx, &ecx, &edx);
1036 memset(vendor, 0, sizeof(vendor));
1037 *((unsigned int *)&vendor[0]) = ebx;
1038 *((unsigned int *)&vendor[4]) = edx;
1039 *((unsigned int *)&vendor[8]) = ecx;
1040 if (strncmp(vendor, "GenuineIntel", 12) != 0)
1042 cpuid(1, &eax, &ebx, &ecx, &edx);
1043 family = (eax >> 8) & 0x0f;
1044 model = (eax >> 4) & 0x0f;
1048 case 7: // Pentium III, Pentium III Xeon (model 7)
1049 case 8: // Pentium III, Pentium III Xeon, Celeron (model 8)
1050 case 9: // Pentium M
1052 Intel recently announced its new technology for mobile platforms,
1053 named Centrino, and presents it as a big advance in mobile PCs.
1054 One of the main part of Centrino consists in a brand new CPU,
1055 the Pentium M, codenamed Banias, that we'll study in this review.
1056 A particularity of this CPU is that it was designed for mobile platform
1057 exclusively, unlike previous mobile CPU (Pentium III-M, Pentium 4-M)
1058 that share the same micro-architecture as their desktop counterparts.
1059 The Pentium M introduces a new micro-architecture, adapted for mobility
1060 constraints, and that is halfway between the Pentium III and the Pentium 4.
1061 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1063 case 10: // Pentium III Xeon (model A)
1064 case 11: // Pentium III (model B)
1070 static int is_pentium4()
1072 unsigned int eax, ebx, ecx, edx, family, model;
1074 cpuid(0, &eax, &ebx, &ecx, &edx);
1075 memset(vendor, 0, sizeof(vendor));
1076 *((unsigned int *)&vendor[0]) = ebx;
1077 *((unsigned int *)&vendor[4]) = edx;
1078 *((unsigned int *)&vendor[8]) = ecx;
1079 if (strncmp(vendor, "GenuineIntel", 12) != 0)
1081 cpuid(1, &eax, &ebx, &ecx, &edx);
1082 family = (eax >> 8) & 0x0f;
1083 model = (eax >> 4) & 0x0f;
1087 case 0: // Pentium 4, Pentium 4 Xeon (0.18um)
1088 case 1: // Pentium 4, Pentium 4 Xeon MP, Celeron (0.18um)
1089 case 2: // Pentium 4, Mobile Pentium 4-M,
1090 // Pentium 4 Xeon, Pentium 4 Xeon MP,
1091 // Celeron, Mobile Celron (0.13um)
1092 case 3: // Pentium 4, Celeron (0.09um)
1100 #if defined(__linux__) && defined(__powerpc__)
1101 static jmp_buf mfspr_jmpbuf;
1103 static void mfspr_ill(int notused)
1105 longjmp(mfspr_jmpbuf, -1);
1111 static void defaultMachine(/*@out@*/ const char ** arch,
1112 /*@out@*/ const char ** os)
1113 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
1114 /*@modifies *arch, *os, rpmGlobalMacroContext, fileSystem, internalState @*/
1116 static struct utsname un;
1117 static int gotDefaults = 0;
1122 while (!gotDefaults) {
1123 if (!rpmPlatform(platform)) {
1125 s = rpmExpand("%{_host_cpu}", NULL);
1127 strncpy(un.machine, s, sizeof(un.machine));
1128 un.machine[sizeof(un.machine)-1] = '\0';
1131 s = rpmExpand("%{_host_os}", NULL);
1133 strncpy(un.sysname, s, sizeof(un.sysname));
1134 un.sysname[sizeof(un.sysname)-1] = '\0';
1143 #if !defined(__linux__)
1145 /* USUALLY un.sysname on sinix does start with the word "SINIX"
1146 * let's be absolutely sure
1148 strncpy(un.sysname, "SINIX", sizeof(un.sysname));
1151 if (!strcmp(un.sysname, "AIX")) {
1152 strcpy(un.machine, __power_pc() ? "ppc" : "rs6000");
1153 sprintf(un.sysname,"aix%s.%s", un.version, un.release);
1155 else if(!strcmp(un.sysname, "Darwin")) {
1157 strcpy(un.machine, "ppc");
1158 #else ifdef __i386__
1159 strcpy(un.machine, "i386");
1162 else if (!strcmp(un.sysname, "SunOS")) {
1163 if (!strncmp(un.release,"4", 1)) /* SunOS 4.x */ {
1166 (un.release[fd] != 0 && (fd < sizeof(un.release)));
1168 if (!xisdigit(un.release[fd]) && (un.release[fd] != '.')) {
1170 /*@innerbreak@*/ break;
1173 sprintf(un.sysname,"sunos%s",un.release);
1176 else /* Solaris 2.x: n.x.x becomes n-3.x.x */
1177 sprintf(un.sysname, "solaris%1d%s", atoi(un.release)-3,
1178 un.release+1+(atoi(un.release)/10));
1180 /* Solaris on Intel hardware reports i86pc instead of i386
1181 * (at least on 2.6 and 2.8)
1183 if (!strcmp(un.machine, "i86pc"))
1184 sprintf(un.machine, "i386");
1186 else if (!strcmp(un.sysname, "HP-UX"))
1187 /*make un.sysname look like hpux9.05 for example*/
1188 sprintf(un.sysname, "hpux%s", strpbrk(un.release, "123456789"));
1189 else if (!strcmp(un.sysname, "OSF1"))
1190 /*make un.sysname look like osf3.2 for example*/
1191 sprintf(un.sysname, "osf%s", strpbrk(un.release, "123456789"));
1192 else if (!strncmp(un.sysname, "IP", 2))
1193 un.sysname[2] = '\0';
1194 else if (!strncmp(un.sysname, "SINIX", 5)) {
1195 sprintf(un.sysname, "sinix%s",un.release);
1196 if (!strncmp(un.machine, "RM", 2))
1197 sprintf(un.machine, "mips");
1199 else if ((!strncmp(un.machine, "34", 2) ||
1200 !strncmp(un.machine, "33", 2)) && \
1201 !strncmp(un.release, "4.0", 3))
1203 /* we are on ncr-sysv4 */
1204 char * prelid = NULL;
1205 FD_t fd = Fopen("/etc/.relid", "r.fdio");
1208 if (fd != NULL && !Ferror(fd)) {
1209 chptr = xcalloc(1, 256);
1210 { int irelid = Fread(chptr, sizeof(*chptr), 256, fd);
1212 /* example: "112393 RELEASE 020200 Version 01 OS" */
1214 if ((prelid = strstr(chptr, "RELEASE "))){
1215 prelid += strlen("RELEASE ")+1;
1216 sprintf(un.sysname,"ncr-sysv4.%.*s",1,prelid);
1221 chptr = _free (chptr);
1224 if (!gotit) /* parsing /etc/.relid file failed? */
1225 strcpy(un.sysname,"ncr-sysv4");
1226 /* wrong, just for now, find out how to look for i586 later*/
1227 strcpy(un.machine,"i486");
1230 #endif /* __linux__ */
1232 /* get rid of the hyphens in the sysname */
1233 for (chptr = un.machine; *chptr != '\0'; chptr++)
1234 if (*chptr == '/') *chptr = '-';
1236 # if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL)
1238 strcpy(un.machine, "mipsel");
1239 # elif defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB)
1241 strcpy(un.machine, "mips");
1244 # if defined(__hpux) && defined(_SC_CPU_VERSION)
1246 # if !defined(CPU_PA_RISC1_2)
1247 # define CPU_PA_RISC1_2 0x211 /* HP PA-RISC1.2 */
1249 # if !defined(CPU_PA_RISC2_0)
1250 # define CPU_PA_RISC2_0 0x214 /* HP PA-RISC2.0 */
1252 int cpu_version = sysconf(_SC_CPU_VERSION);
1254 # if defined(CPU_HP_MC68020)
1255 if (cpu_version == CPU_HP_MC68020)
1256 strcpy(un.machine, "m68k");
1258 # if defined(CPU_HP_MC68030)
1259 if (cpu_version == CPU_HP_MC68030)
1260 strcpy(un.machine, "m68k");
1262 # if defined(CPU_HP_MC68040)
1263 if (cpu_version == CPU_HP_MC68040)
1264 strcpy(un.machine, "m68k");
1267 # if defined(CPU_PA_RISC1_0)
1268 if (cpu_version == CPU_PA_RISC1_0)
1269 strcpy(un.machine, "hppa1.0");
1271 # if defined(CPU_PA_RISC1_1)
1272 if (cpu_version == CPU_PA_RISC1_1)
1273 strcpy(un.machine, "hppa1.1");
1275 # if defined(CPU_PA_RISC1_2)
1276 if (cpu_version == CPU_PA_RISC1_2)
1277 strcpy(un.machine, "hppa1.2");
1279 # if defined(CPU_PA_RISC2_0)
1280 if (cpu_version == CPU_PA_RISC2_0)
1281 strcpy(un.machine, "hppa2.0");
1286 # if defined(__linux__) && defined(__sparc__)
1287 if (!strcmp(un.machine, "sparc")) {
1288 #define PERS_LINUX 0x00000000
1289 #define PERS_LINUX_32BIT 0x00800000
1290 #define PERS_LINUX32 0x00000008
1292 extern int personality(unsigned long);
1295 oldpers = personality(PERS_LINUX_32BIT);
1296 if (oldpers != -1) {
1297 if (personality(PERS_LINUX) != -1) {
1299 if (! strcmp(un.machine, "sparc64")) {
1300 strcpy(un.machine, "sparcv9");
1301 oldpers = PERS_LINUX32;
1304 personality(oldpers);
1307 # endif /* sparc*-linux */
1309 # if defined(__GNUC__) && defined(__alpha__)
1311 unsigned long amask, implver;
1312 register long v0 __asm__("$0") = -1;
1313 __asm__ (".long 0x47e00c20" : "=r"(v0) : "0"(v0));
1315 __asm__ (".long 0x47e03d80" : "=r"(v0));
1320 case 0: strcpy(un.machine, "alphaev5"); break;
1321 case 1: strcpy(un.machine, "alphaev56"); break;
1322 case 0x101: strcpy(un.machine, "alphapca56"); break;
1327 case 0x303: strcpy(un.machine, "alphaev6"); break;
1328 case 0x307: strcpy(un.machine, "alphaev67"); break;
1335 # if defined(__linux__) && defined(__i386__)
1337 char class = (char) (RPMClass() | '0');
1339 if ((class == '6' && is_athlon()) || class == '7')
1340 strcpy(un.machine, "athlon");
1341 else if (is_pentium4())
1342 strcpy(un.machine, "pentium4");
1343 else if (is_pentium3())
1344 strcpy(un.machine, "pentium3");
1345 else if (strchr("3456", un.machine[1]) && un.machine[1] != class)
1346 un.machine[1] = class;
1350 /* the uname() result goes through the arch_canon table */
1351 canon = lookupInCanonTable(un.machine,
1352 tables[RPM_MACHTABLE_INSTARCH].canons,
1353 tables[RPM_MACHTABLE_INSTARCH].canonsLength);
1355 strcpy(un.machine, canon->short_name);
1357 canon = lookupInCanonTable(un.sysname,
1358 tables[RPM_MACHTABLE_INSTOS].canons,
1359 tables[RPM_MACHTABLE_INSTOS].canonsLength);
1361 strcpy(un.sysname, canon->short_name);
1366 if (arch) *arch = un.machine;
1367 if (os) *os = un.sysname;
1370 static /*@observer@*/ /*@null@*/
1371 const char * rpmGetVarArch(int var, /*@null@*/ const char * arch)
1374 const struct rpmvarValue * next;
1376 if (arch == NULL) arch = current[ARCH];
1379 next = &values[var];
1381 if (next->arch && !strcmp(next->arch, arch)) return next->value;
1386 next = values + var;
1387 while (next && next->arch) next = next->next;
1389 return next ? next->value : NULL;
1392 const char *rpmGetVar(int var)
1394 return rpmGetVarArch(var, NULL);
1397 /* this doesn't free the passed pointer! */
1398 static void freeRpmVar(/*@only@*/ struct rpmvarValue * orig)
1399 /*@modifies *orig @*/
1401 struct rpmvarValue * next, * var = orig;
1405 var->arch = _free(var->arch);
1406 var->value = _free(var->value);
1409 if (var != orig) var = _free(var);
1415 void rpmSetVar(int var, const char * val)
1416 /*@globals values @*/
1417 /*@modifies values @*/
1419 /*@-immediatetrans@*/
1420 freeRpmVar(&values[var]);
1421 /*@=immediatetrans@*/
1422 values[var].value = (val ? xstrdup(val) : NULL);
1425 static void rpmSetVarArch(int var, const char * val, const char * arch)
1427 struct rpmvarValue * next = values + var;
1431 while (next->next) {
1432 if (next->arch && !strcmp(next->arch, arch)) break;
1436 while (next->next) {
1437 if (!next->arch) break;
1442 /*@-nullpass@*/ /* LCL: arch != NULL here. */
1443 if (next->arch && arch && !strcmp(next->arch, arch)) {
1445 next->value = _free(next->value);
1446 next->arch = _free(next->arch);
1447 } else if (next->arch || arch) {
1448 next->next = xmalloc(sizeof(*next->next));
1456 next->value = _free(next->value);
1457 next->value = xstrdup(val);
1458 next->arch = (arch ? xstrdup(arch) : NULL);
1461 void rpmSetTables(int archTable, int osTable)
1462 /*@globals currTables @*/
1463 /*@modifies currTables @*/
1465 const char * arch, * os;
1467 defaultMachine(&arch, &os);
1469 if (currTables[ARCH] != archTable) {
1470 currTables[ARCH] = archTable;
1471 rebuildCompatTables(ARCH, arch);
1474 if (currTables[OS] != osTable) {
1475 currTables[OS] = osTable;
1476 rebuildCompatTables(OS, os);
1480 int rpmMachineScore(int type, const char * name)
1482 machEquivInfo info = machEquivSearch(&tables[type].equiv, name);
1483 return (info != NULL ? info->score : 0);
1486 void rpmGetMachine(const char ** arch, const char ** os)
1489 *arch = current[ARCH];
1495 void rpmSetMachine(const char * arch, const char * os)
1496 /*@globals current @*/
1497 /*@modifies current @*/
1499 const char * host_cpu, * host_os;
1501 defaultMachine(&host_cpu, &host_os);
1505 if (tables[currTables[ARCH]].hasTranslate)
1506 arch = lookupInDefaultTable(arch,
1507 tables[currTables[ARCH]].defaults,
1508 tables[currTables[ARCH]].defaultsLength);
1510 if (arch == NULL) return; /* XXX can't happen */
1514 if (tables[currTables[OS]].hasTranslate)
1515 os = lookupInDefaultTable(os,
1516 tables[currTables[OS]].defaults,
1517 tables[currTables[OS]].defaultsLength);
1519 if (os == NULL) return; /* XXX can't happen */
1521 if (!current[ARCH] || strcmp(arch, current[ARCH])) {
1522 current[ARCH] = _free(current[ARCH]);
1523 current[ARCH] = xstrdup(arch);
1524 rebuildCompatTables(ARCH, host_cpu);
1527 if (!current[OS] || strcmp(os, current[OS])) {
1528 char * t = xstrdup(os);
1529 current[OS] = _free(current[OS]);
1531 * XXX Capitalizing the 'L' is needed to insure that old
1532 * XXX os-from-uname (e.g. "Linux") is compatible with the new
1533 * XXX os-from-platform (e.g "linux" from "sparc-*-linux").
1534 * XXX A copy of this string is embedded in headers and is
1535 * XXX used by rpmInstallPackage->{os,arch}Okay->rpmMachineScore->
1536 * XXX to verify correct arch/os from headers.
1538 if (!strcmp(t, "linux"))
1542 rebuildCompatTables(OS, host_os);
1546 static void rebuildCompatTables(int type, const char * name)
1549 machFindEquivs(&tables[currTables[type]].cache,
1550 &tables[currTables[type]].equiv,
1554 static void getMachineInfo(int type, /*@null@*/ /*@out@*/ const char ** name,
1555 /*@null@*/ /*@out@*/int * num)
1556 /*@modifies *name, *num @*/
1559 int which = currTables[type];
1561 /* use the normal canon tables, even if we're looking up build stuff */
1562 if (which >= 2) which -= 2;
1564 canon = lookupInCanonTable(current[type],
1565 tables[which].canons,
1566 tables[which].canonsLength);
1569 if (num) *num = canon->num;
1570 if (name) *name = canon->short_name;
1572 if (num) *num = 255;
1573 if (name) *name = current[type];
1575 if (tables[currTables[type]].hasCanon) {
1576 rpmMessage(RPMMESS_WARNING, _("Unknown system: %s\n"), current[type]);
1577 rpmMessage(RPMMESS_WARNING, _("Please contact %s\n"), PACKAGE_BUGREPORT);
1582 void rpmGetArchInfo(const char ** name, int * num)
1584 getMachineInfo(ARCH, name, num);
1587 void rpmGetOsInfo(const char ** name, int * num)
1589 getMachineInfo(OS, name, num);
1592 static void rpmRebuildTargetVars(const char ** target, const char ** canontarget)
1595 char *ca = NULL, *co = NULL, *ct = NULL;
1598 /* Rebuild the compat table to recalculate the current target arch. */
1600 rpmSetMachine(NULL, NULL);
1601 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS);
1602 rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
1605 if (target && *target) {
1607 /* Set arch and os from specified build target */
1608 ca = xstrdup(*target);
1609 if ((c = strchr(ca, '-')) != NULL) {
1612 if ((co = strrchr(c, '-')) == NULL) {
1615 if (!xstrcasecmp(co, "-gnu"))
1617 if ((co = strrchr(c, '-')) == NULL)
1622 if (co != NULL) co = xstrdup(co);
1625 const char *a = NULL;
1626 const char *o = NULL;
1627 /* Set build target from rpm arch and os */
1628 rpmGetArchInfo(&a, NULL);
1629 ca = (a) ? xstrdup(a) : NULL;
1630 rpmGetOsInfo(&o, NULL);
1631 co = (o) ? xstrdup(o) : NULL;
1635 /* If still not set, Set target arch/os from default uname(2) values */
1637 const char *a = NULL;
1638 defaultMachine(&a, NULL);
1639 ca = (a) ? xstrdup(a) : NULL;
1641 for (x = 0; ca[x] != '\0'; x++)
1642 ca[x] = xtolower(ca[x]);
1645 const char *o = NULL;
1646 defaultMachine(NULL, &o);
1647 co = (o) ? xstrdup(o) : NULL;
1649 for (x = 0; co[x] != '\0'; x++)
1650 co[x] = xtolower(co[x]);
1652 /* XXX For now, set canonical target to arch-os */
1654 ct = xmalloc(strlen(ca) + sizeof("-") + strlen(co));
1655 sprintf(ct, "%s-%s", ca, co);
1659 * XXX All this macro pokery/jiggery could be achieved by doing a delayed
1660 * rpmInitMacros(NULL, PER-PLATFORM-MACRO-FILE-NAMES);
1662 delMacro(NULL, "_target");
1663 addMacro(NULL, "_target", NULL, ct, RMIL_RPMRC);
1664 delMacro(NULL, "_target_cpu");
1665 addMacro(NULL, "_target_cpu", NULL, ca, RMIL_RPMRC);
1666 delMacro(NULL, "_target_os");
1667 addMacro(NULL, "_target_os", NULL, co, RMIL_RPMRC);
1669 * XXX Make sure that per-arch optflags is initialized correctly.
1671 { const char *optflags = rpmGetVarArch(RPMVAR_OPTFLAGS, ca);
1672 if (optflags != NULL) {
1673 delMacro(NULL, "optflags");
1674 addMacro(NULL, "optflags", NULL, optflags, RMIL_RPMRC);
1690 void rpmFreeRpmrc(void)
1691 /*@globals current, tables, values, defaultsInitialized,
1692 platpat, nplatpat @*/
1693 /*@modifies current, tables, values, defaultsInitialized,
1694 platpat, nplatpat @*/
1698 /*@-onlyunqglobaltrans -unqualifiedtrans @*/
1700 for (i = 0; i < nplatpat; i++)
1701 platpat[i] = _free(platpat[i]);
1702 platpat = _free(platpat);
1703 /*@-onlyunqglobaltrans =unqualifiedtrans @*/
1706 for (i = 0; i < RPM_MACHTABLE_COUNT; i++) {
1709 if (t->equiv.list) {
1710 for (j = 0; j < t->equiv.count; j++)
1711 t->equiv.list[j].name = _free(t->equiv.list[j].name);
1712 t->equiv.list = _free(t->equiv.list);
1715 if (t->cache.cache) {
1716 for (j = 0; j < t->cache.size; j++) {
1718 e = t->cache.cache + j;
1720 /*@innercontinue@*/ continue;
1721 e->name = _free(e->name);
1723 for (k = 0; k < e->count; k++)
1724 e->equivs[k] = _free(e->equivs[k]);
1725 e->equivs = _free(e->equivs);
1728 t->cache.cache = _free(t->cache.cache);
1732 for (j = 0; j < t->defaultsLength; j++) {
1733 t->defaults[j].name = _free(t->defaults[j].name);
1734 t->defaults[j].defName = _free(t->defaults[j].defName);
1736 t->defaults = _free(t->defaults);
1737 t->defaultsLength = 0;
1740 for (j = 0; j < t->canonsLength; j++) {
1741 t->canons[j].name = _free(t->canons[j].name);
1742 t->canons[j].short_name = _free(t->canons[j].short_name);
1744 t->canons = _free(t->canons);
1745 t->canonsLength = 0;
1749 for (i = 0; i < RPMVAR_NUM; i++) {
1750 /*@only@*/ /*@null@*/ struct rpmvarValue * vp;
1751 while ((vp = values[i].next) != NULL) {
1752 values[i].next = vp->next;
1753 vp->value = _free(vp->value);
1754 vp->arch = _free(vp->arch);
1757 values[i].value = _free(values[i].value);
1758 values[i].arch = _free(values[i].arch);
1760 current[OS] = _free(current[OS]);
1761 current[ARCH] = _free(current[ARCH]);
1762 defaultsInitialized = 0;
1763 /*@-globstate -nullstate@*/ /* FIX: platpat/current may be NULL */
1765 /*@=globstate =nullstate@*/
1769 * Read rpmrc (and macro) configuration file(s).
1770 * @param rcfiles colon separated files to read (NULL uses default)
1771 * @return 0 on succes
1773 static int rpmReadRC(/*@null@*/ const char * rcfiles)
1774 /*@globals defaultsInitialized, rpmGlobalMacroContext,
1775 rpmCLIMacroContext, h_errno, fileSystem, internalState @*/
1776 /*@modifies defaultsInitialized, rpmGlobalMacroContext,
1777 fileSystem, internalState @*/
1779 char *myrcfiles, *r, *re;
1782 if (!defaultsInitialized) {
1784 defaultsInitialized = 1;
1787 if (rcfiles == NULL)
1788 rcfiles = defrcfiles;
1790 /* Read each file in rcfiles. */
1792 for (r = myrcfiles = xstrdup(rcfiles); r && *r != '\0'; r = re) {
1796 /* Get pointer to rest of files */
1797 for (re = r; (re = strchr(re, ':')) != NULL; re++) {
1798 if (!(re[1] == '/' && re[2] == '/'))
1799 /*@innerbreak@*/ break;
1801 if (re && *re == ':')
1806 /* Expand ~/ to $HOME/ */
1808 if (r[0] == '~' && r[1] == '/') {
1809 const char * home = getenv("HOME");
1811 /* XXX Only /usr/lib/rpm/rpmrc must exist in default rcfiles list */
1812 if (rcfiles == defrcfiles && myrcfiles != r)
1814 rpmError(RPMERR_RPMRC, _("Cannot expand %s\n"), r);
1818 if (strlen(home) > (sizeof(fn) - strlen(r))) {
1819 rpmError(RPMERR_RPMRC, _("Cannot read %s, HOME is too large.\n"),
1827 strncat(fn, r, sizeof(fn) - (strlen(fn) + 1));
1828 fn[sizeof(fn)-1] = '\0';
1830 /* Read another rcfile */
1831 fd = Fopen(fn, "r.fpio");
1832 if (fd == NULL || Ferror(fd)) {
1833 /* XXX Only /usr/lib/rpm/rpmrc must exist in default rcfiles list */
1834 if (rcfiles == defrcfiles && myrcfiles != r)
1836 rpmError(RPMERR_RPMRC, _("Unable to open %s for reading: %s.\n"),
1841 rc = doReadRC(fd, fn);
1845 myrcfiles = _free(myrcfiles);
1849 rpmSetMachine(NULL, NULL); /* XXX WTFO? Why bother? */
1851 { const char *mfpath;
1853 if ((mfpath = rpmGetVar(RPMVAR_MACROFILES)) != NULL) {
1854 mfpath = xstrdup(mfpath);
1855 rpmInitMacros(NULL, mfpath);
1856 mfpath = _free(mfpath);
1864 int rpmReadConfigFiles(const char * file, const char * target)
1867 /* Preset target macros */
1868 /*@-nullstate@*/ /* FIX: target can be NULL */
1869 rpmRebuildTargetVars(&target, NULL);
1871 /* Read the files */
1872 if (rpmReadRC(file)) return -1;
1874 /* Reset target macros */
1875 rpmRebuildTargetVars(&target, NULL);
1878 /* Finally set target platform */
1879 { const char *cpu = rpmExpand("%{_target_cpu}", NULL);
1880 const char *os = rpmExpand("%{_target_os}", NULL);
1881 rpmSetMachine(cpu, os);
1886 /* Force Lua state initialization */
1888 (void)rpmluaGetPrintBuffer(NULL);
1894 int rpmShowRC(FILE * fp)
1896 struct rpmOption *opt;
1898 machEquivTable equivTable;
1900 /* the caller may set the build arch which should be printed here */
1901 fprintf(fp, "ARCHITECTURE AND OS:\n");
1902 fprintf(fp, "build arch : %s\n", current[ARCH]);
1904 fprintf(fp, "compatible build archs:");
1905 equivTable = &tables[RPM_MACHTABLE_BUILDARCH].equiv;
1906 for (i = 0; i < equivTable->count; i++)
1907 fprintf(fp," %s", equivTable->list[i].name);
1910 fprintf(fp, "build os : %s\n", current[OS]);
1912 fprintf(fp, "compatible build os's :");
1913 equivTable = &tables[RPM_MACHTABLE_BUILDOS].equiv;
1914 for (i = 0; i < equivTable->count; i++)
1915 fprintf(fp," %s", equivTable->list[i].name);
1918 rpmSetTables(RPM_MACHTABLE_INSTARCH, RPM_MACHTABLE_INSTOS);
1919 rpmSetMachine(NULL, NULL); /* XXX WTFO? Why bother? */
1921 fprintf(fp, "install arch : %s\n", current[ARCH]);
1922 fprintf(fp, "install os : %s\n", current[OS]);
1924 fprintf(fp, "compatible archs :");
1925 equivTable = &tables[RPM_MACHTABLE_INSTARCH].equiv;
1926 for (i = 0; i < equivTable->count; i++)
1927 fprintf(fp," %s", equivTable->list[i].name);
1930 fprintf(fp, "compatible os's :");
1931 equivTable = &tables[RPM_MACHTABLE_INSTOS].equiv;
1932 for (i = 0; i < equivTable->count; i++)
1933 fprintf(fp," %s", equivTable->list[i].name);
1936 fprintf(fp, "\nRPMRC VALUES:\n");
1937 for (i = 0, opt = optionTable; i < optionTableSize; i++, opt++) {
1938 const char *s = rpmGetVar(opt->var);
1939 if (s != NULL || rpmIsVerbose())
1940 fprintf(fp, "%-21s : %s\n", opt->name, s ? s : "(not set)");
1944 fprintf(fp, "Features supported by rpmlib:\n");
1945 rpmShowRpmlibProvides(fp);
1948 rpmDumpMacroTable(NULL, fp);