#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/utsname.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
uname(struct utsname *name)
{
int mib[2], rval;
size_t len;
char *p;
int oerrno;
rval = 0;
bzero(name->sysname, sizeof(name->sysname));
if ((p = getenv("UNAME_s"))) {
strlcpy(name->sysname, p, sizeof(name->sysname));
} else {
mib[0] = CTL_KERN;
mib[1] = KERN_OSTYPE;
len = sizeof(name->sysname);
oerrno = errno;
if (sysctl(mib, 2, name->sysname, &len, NULL, 0) == -1) {
if(errno == ENOMEM)
errno = oerrno;
else
rval = -1;
}
name->sysname[sizeof(name->sysname) - 1] = '\0';
}
bzero(name->nodename, sizeof(name->nodename));
mib[0] = CTL_KERN;
mib[1] = KERN_HOSTNAME;
len = sizeof(name->nodename);
oerrno = errno;
if (sysctl(mib, 2, name->nodename, &len, NULL, 0) == -1) {
if(errno == ENOMEM)
errno = oerrno;
else
rval = -1;
}
name->nodename[sizeof(name->nodename) - 1] = '\0';
if ((p = getenv("UNAME_r"))) {
strlcpy(name->release, p, sizeof(name->release));
} else {
mib[0] = CTL_KERN;
mib[1] = KERN_OSRELEASE;
len = sizeof(name->release);
oerrno = errno;
if (sysctl(mib, 2, name->release, &len, NULL, 0) == -1) {
if(errno == ENOMEM)
errno = oerrno;
else
rval = -1;
}
name->release[sizeof(name->release) - 1] = '\0';
}
bzero(name->version, sizeof(name->version));
if ((p = getenv("UNAME_v"))) {
strlcpy(name->version, p, sizeof(name->version));
} else {
mib[0] = CTL_KERN;
mib[1] = KERN_VERSION;
len = sizeof(name->version);
oerrno = errno;
if (sysctl(mib, 2, name->version, &len, NULL, 0) == -1) {
if (errno == ENOMEM)
errno = oerrno;
else
rval = -1;
}
name->version[sizeof(name->version) - 1] = '\0';
for (p = name->version; len--; ++p) {
if (*p == '\n' || *p == '\t') {
if (len > 1)
*p = ' ';
else
*p = '\0';
}
}
}
bzero(name->machine, sizeof(name->machine));
if ((p = getenv("UNAME_m"))) {
strlcpy(name->machine, p, sizeof(name->machine));
} else {
oerrno = errno;
mib[1] = HW_MACHINE;
mib[0] = CTL_HW;
len = sizeof(name->machine);
if (sysctl(mib, 2, name->machine, &len, NULL, 0) == -1) {
if (errno == ENOMEM) {
errno = oerrno;
} else {
rval = -1;
}
}
name->machine[sizeof(name->machine) - 1] = '\0';
}
return (rval);
}