#ifdef _KERNEL
#include <sys/types.h>
#include <sys/sunddi.h>
#else
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/utsname.h>
#include <sys/systeminfo.h>
#endif
#include <sys/debug.h>
#include <sys/ilstr.h>
static void
bootbanner_expand_template(const char *input, ilstr_t *output)
{
size_t pos = 0;
enum {
ST_REST,
ST_CARET,
} state = ST_REST;
#ifndef _KERNEL
struct utsname utsname;
bzero(&utsname, sizeof (utsname));
(void) uname(&utsname);
#endif
for (;;) {
char c = input[pos];
if (c == '\0') {
break;
}
switch (state) {
case ST_REST:
if (c == '^') {
state = ST_CARET;
} else {
ilstr_append_char(output, c);
}
pos++;
continue;
case ST_CARET:
if (c == '^') {
ilstr_append_char(output, c);
} else if (c == 's') {
ilstr_append_str(output, utsname.sysname);
} else if (c == 'o') {
ilstr_append_str(output, "illumos");
} else if (c == 'r') {
ilstr_append_str(output, utsname.release);
} else if (c == 'v') {
ilstr_append_str(output, utsname.version);
} else if (c == 'w') {
#ifdef _KERNEL
ilstr_aprintf(output, "%u",
NBBY * (uint_t)sizeof (void *));
#else
char *bits;
char buf[32];
int r;
if ((r = sysinfo(SI_ADDRESS_WIDTH, buf,
sizeof (buf))) > 0 &&
r < (int)sizeof (buf)) {
bits = buf;
} else {
bits = "64";
}
ilstr_append_str(output, bits);
#endif
} else {
ilstr_append_str(output, "!^");
ilstr_append_char(output, c);
ilstr_append_str(output, " UNKNOWN!");
}
state = ST_REST;
pos++;
continue;
}
}
}
static void
bootbanner_print_one(ilstr_t *s, void (*printfunc)(const char *, uint_t),
const char *template, uint_t *nump)
{
ilstr_reset(s);
bootbanner_expand_template(template, s);
if (ilstr_errno(s) == ILSTR_ERROR_OK) {
if (!ilstr_is_empty(s)) {
printfunc(ilstr_cstr(s), *nump);
*nump += 1;
}
} else {
char ebuf[128];
snprintf(ebuf, sizeof (ebuf), "boot banner error: %s",
ilstr_errstr(s));
printfunc(ebuf, *nump);
*nump += 1;
}
}
void
bootbanner_print(void (*printfunc)(const char *, uint_t))
{
char sbuf[80 * 4];
ilstr_t s;
uint_t num = 0;
ilstr_init_prealloc(&s, sbuf, sizeof (sbuf));
bootbanner_print_one(&s, printfunc, BOOTBANNER1, &num);
bootbanner_print_one(&s, printfunc, BOOTBANNER2, &num);
bootbanner_print_one(&s, printfunc, BOOTBANNER3, &num);
bootbanner_print_one(&s, printfunc, BOOTBANNER4, &num);
bootbanner_print_one(&s, printfunc, BOOTBANNER5, &num);
ilstr_fini(&s);
}