root/src/system/libroot/posix/sys/uname.c
/*
 * Copyright 2004-2007, Jérôme Duval jerome.duval@free.fr. All rights reserved.
 * Distributed under the terms of the MIT License.
 */


#include <sys/utsname.h>

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <OS.h>
#include <ByteOrder.h>

#include <errno_private.h>
#include <system_revision.h>


int
uname(struct utsname *info)
{
        cpu_topology_node_info root;
        system_info systemInfo;
        const char *platform;
        const char *haikuRevision;
        uint32 count = 1;
        status_t error;
        const char* release = NULL;

        if (!info) {
                __set_errno(B_BAD_VALUE);
                return -1;
        }

        get_system_info(&systemInfo);

        strlcpy(info->sysname, "Haiku", sizeof(info->sysname));

        haikuRevision = __get_haiku_revision();
        if (haikuRevision[0] != '\0')
                snprintf(info->version, sizeof(info->version), "%s ", haikuRevision);
        else
                info->version[0] = '\0';
        strlcat(info->version, systemInfo.kernel_build_date, sizeof(info->version));
        strlcat(info->version, " ", sizeof(info->version));
        strlcat(info->version, systemInfo.kernel_build_time, sizeof(info->version));

        switch (systemInfo.kernel_version) {
                case B_HAIKU_VERSION_1_PRE_BETA_5:      release = "R1~beta4+development"; break;
                case B_HAIKU_VERSION_1_BETA_5:          release = "R1~beta5"; break;
                case B_HAIKU_VERSION_1_PRE_BETA_6:      release = "R1~beta5+development"; break;
                case B_HAIKU_VERSION_1_BETA_6:          release = "R1~beta6"; break;
                case B_HAIKU_VERSION_1_PRE_BETA_7:      release = "R1~beta6+development"; break;
                case B_HAIKU_VERSION_1:                         release = "R1"; break;
                default:
                        snprintf(info->release, sizeof(info->release), "%" B_PRId64,
                                systemInfo.kernel_version);
                        break;
        }
        if (release != NULL)
                strlcpy(info->release, release, sizeof(info->release));

        error = get_cpu_topology_info(&root, &count);
        if (error != B_OK || count < 1)
                platform = "unknown";
        else {
                switch (root.data.root.platform) {
                        case B_CPU_x86:
                                platform = "BePC";
                                break;
                        case B_CPU_x86_64:
                                platform = "x86_64";
                                break;
                        case B_CPU_PPC:
                                platform = "ppc";
                                break;
                        case B_CPU_PPC_64:
                                platform = "ppc64";
                                break;
                        case B_CPU_M68K:
                                platform = "m68k";
                                break;
                        case B_CPU_ARM:
                                platform = "arm";
                                break;
                        case B_CPU_ARM_64:
                                platform = "arm64";
                                break;
                        case B_CPU_RISC_V:
                                platform = "riscv64";
                                break;
                        case B_CPU_UNKNOWN:
                        default:
                                platform = "unknown";
                                break;
                }
        }

        strlcpy(info->machine, platform, sizeof(info->machine));

        if (gethostname(info->nodename, sizeof(info->nodename)) != 0)
                strlcpy(info->nodename, "unknown", sizeof(info->nodename));

        return 0;
}