root/src/system/libroot/posix/unistd/hostname.cpp
/*
 * Copyright 2002-2014, Axel Dörfler, axeld@pinc-software.de.
 * Distributed under the terms of the MIT License.
 */


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

#include <FindDirectory.h>
#include <StorageDefs.h>

#include <errno_private.h>
#include <find_directory_private.h>


static status_t
get_path(char *path, bool create)
{
        status_t status = __find_directory(B_SYSTEM_SETTINGS_DIRECTORY, -1, create,
                path, B_PATH_NAME_LENGTH);
        if (status != B_OK)
                return status;

        strlcat(path, "/network", B_PATH_NAME_LENGTH);
        if (create)
                mkdir(path, 0755);
        strlcat(path, "/hostname", B_PATH_NAME_LENGTH);
        return B_OK;
}


extern "C" int
sethostname(const char *hostName, size_t nameSize)
{
        if (nameSize > MAXHOSTNAMELEN) {
                __set_errno(EINVAL);
                return -1;
        }

        char path[B_PATH_NAME_LENGTH];
        if (get_path(path, false) != B_OK) {
                __set_errno(B_ERROR);
                return -1;
        }

        int file = open(path, O_WRONLY | O_CREAT, 0644);
        if (file < 0)
                return -1;

        ftruncate(file, nameSize + 1);

        if (write(file, hostName, nameSize) != (ssize_t)nameSize
                || write(file, "\n", 1) != 1) {
                close(file);
                return -1;
        }

        close(file);
        return 0;
}


extern "C" int
gethostname(char *hostName, size_t nameSize)
{
        // look up hostname from network settings hostname file

        char path[B_PATH_NAME_LENGTH];
        if (get_path(path, false) != B_OK) {
                __set_errno(B_ERROR);
                return -1;
        }

        int file = open(path, O_RDONLY);
        if (file < 0)
                return -1;

        nameSize = min_c(nameSize, MAXHOSTNAMELEN);

        int length = read(file, hostName, nameSize - 1);
        close(file);

        if (length < 0)
                return -1;

        hostName[length] = '\0';

        char *end = strpbrk(hostName, "\r\n\t");
        if (end != NULL)
                end[0] = '\0';

        return 0;
}