#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/param.h>
#include <sys/idprom.h>
#include <sys/promif.h>
#include <sys/salib.h>
#include <sys/platnames.h>
#define MAXNMLEN 1024
extern char *default_name;
extern char *default_path;
enum ia_state_mach {
STATE_NAME,
STATE_COMPAT_INIT,
STATE_COMPAT,
STATE_DEFAULT,
STATE_FINI
};
static char *
get_impl_arch_name(enum ia_state_mach *state, int use_default)
{
static char iarch[MAXNMLEN];
static int len;
static char *ia;
pnode_t n;
char *cp;
char *namename;
newstate:
switch (*state) {
case STATE_NAME:
*state = STATE_COMPAT_INIT;
namename = OBP_NAME;
n = (pnode_t)prom_rootnode();
len = prom_getproplen(n, namename);
if (len <= 0 || len >= MAXNMLEN)
goto newstate;
(void) prom_getprop(n, namename, iarch);
iarch[len] = '\0';
ia = iarch;
break;
case STATE_COMPAT_INIT:
*state = STATE_COMPAT;
namename = OBP_COMPATIBLE;
n = (pnode_t)prom_rootnode();
len = prom_getproplen(n, namename);
if (len <= 0 || len >= MAXNMLEN) {
*state = STATE_DEFAULT;
goto newstate;
}
(void) prom_getprop(n, namename, iarch);
iarch[len] = '\0';
ia = iarch;
break;
case STATE_COMPAT:
while (*ia++)
;
if ((ia - iarch) >= len) {
*state = STATE_DEFAULT;
goto newstate;
}
break;
case STATE_DEFAULT:
*state = STATE_FINI;
if (!use_default || default_name == NULL)
goto newstate;
(void) strcpy(iarch, default_name);
ia = iarch;
break;
case STATE_FINI:
return (NULL);
}
for (cp = ia; *cp; cp++)
if (*cp == '/' || *cp == ' ' || *cp == '\t')
*cp = '_';
return (ia);
}
static void
make_platform_path(char *fullpath, char *iarch, char *filename)
{
(void) strcpy(fullpath, "/platform/");
(void) strcat(fullpath, iarch);
if (filename != NULL) {
(void) strcat(fullpath, "/");
(void) strcat(fullpath, filename);
}
}
int
find_platform_dir(int (*isdirfn)(char *), char *iarch, int use_default)
{
char fullpath[MAXPATHLEN];
char *ia;
enum ia_state_mach state = STATE_NAME;
while ((ia = get_impl_arch_name(&state, use_default)) != NULL) {
make_platform_path(fullpath, ia, NULL);
if (((*isdirfn)(fullpath)) != 0) {
(void) strcpy(iarch, ia);
return (1);
}
}
return (0);
}
int
open_platform_file(
char *filename,
int (*openfn)(char *, void *),
void *arg,
char *fullpath)
{
char *ia;
int fd;
enum ia_state_mach state = STATE_NAME;
while ((ia = get_impl_arch_name(&state, 1)) != NULL) {
make_platform_path(fullpath, ia, filename);
if ((fd = (*openfn)(fullpath, arg)) != -1)
return (fd);
}
return (-1);
}