// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/processargs/processargs.h>
#include <zircon/syscalls.h>

// TODO(mcgrathr): Is there a better error code to use for marshalling
// protocol violations?
#define MALFORMED ZX_ERR_INVALID_ARGS

zx_status_t processargs_message_size(zx_handle_t channel,
                                     uint32_t* nbytes, uint32_t* nhandles) {
    zx_status_t status = _zx_channel_read(
        channel, 0, NULL, NULL, 0, 0, nbytes, nhandles);
    if (status == ZX_ERR_BUFFER_TOO_SMALL)
        status = ZX_OK;
    return status;
}

zx_status_t processargs_read(zx_handle_t bootstrap,
                             void* buffer, uint32_t nbytes,
                             zx_handle_t handles[], uint32_t nhandles,
                             zx_proc_args_t** pargs,
                             uint32_t** handle_info) {
    if (nbytes < sizeof(zx_proc_args_t))
        return ZX_ERR_INVALID_ARGS;
    if ((uintptr_t)buffer % alignof(zx_proc_args_t) != 0)
        return ZX_ERR_INVALID_ARGS;

    uint32_t got_bytes = 0;
    uint32_t got_handles = 0;
    zx_status_t status = _zx_channel_read(bootstrap, 0, buffer, handles, nbytes,
                                          nhandles, &got_bytes, &got_handles);
    if (status != ZX_OK)
        return status;
    if (got_bytes != nbytes || got_handles != nhandles)
        return ZX_ERR_INVALID_ARGS;

    zx_proc_args_t* const pa = buffer;

    if (pa->protocol != ZX_PROCARGS_PROTOCOL ||
        pa->version != ZX_PROCARGS_VERSION)
        return MALFORMED;

    if (pa->handle_info_off < sizeof(*pa) ||
        pa->handle_info_off % alignof(uint32_t) != 0 ||
        pa->handle_info_off > nbytes ||
        (nbytes - pa->handle_info_off) / sizeof(uint32_t) < nhandles)
        return MALFORMED;

    if (pa->args_num > 0 && (pa->args_off < sizeof(*pa) ||
                             pa->args_off > nbytes ||
                             (nbytes - pa->args_off) < pa->args_num))
        return MALFORMED;

    if (pa->environ_num > 0 && (pa->environ_off < sizeof(*pa) ||
                                pa->environ_off > nbytes ||
                                (nbytes - pa->environ_off) < pa->environ_num))
        return MALFORMED;

    *pargs = pa;
    *handle_info = (void*)&((uint8_t*)buffer)[pa->handle_info_off];
    return ZX_OK;
}

static zx_status_t unpack_strings(char* buffer, uint32_t bytes, char* result[],
                                  uint32_t off, uint32_t num) {
    char* p = &buffer[off];
    for (uint32_t i = 0; i < num; ++i) {
        result[i] = p;
        do {
            if (p >= &buffer[bytes])
                return MALFORMED;
        } while (*p++ != '\0');
    }
    result[num] = NULL;
    return ZX_OK;
}

zx_status_t processargs_strings(void* msg, uint32_t bytes,
                                char* argv[], char* envp[], char* names[]) {
    zx_proc_args_t* const pa = msg;
    zx_status_t status = ZX_OK;
    if (argv != NULL) {
        status = unpack_strings(msg, bytes, argv, pa->args_off, pa->args_num);
    }
    if (envp != NULL && status == ZX_OK) {
        status = unpack_strings(msg, bytes, envp,
                                pa->environ_off, pa->environ_num);
    }
    if (names != NULL && status == ZX_OK) {
        status = unpack_strings(msg, bytes, names, pa->names_off, pa->names_num);
    }
    return status;
}
