/*
 * Copyright (C) 2007-2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * pmsg write handler
 */

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

#include <log/log.h>
#include <log/logger.h>

#include <private/android_filesystem_config.h>
#include <private/android_logger.h>

#include <sys/system_properties.h>

#include "config_write.h"
#include "log_portability.h"
#include "logger.h"

static int pmsgOpen();
static void pmsgClose();
static int pmsgAvailable(log_id_t logId);
static int pmsgWrite(log_id_t logId, struct timespec *ts,
                      struct iovec *vec, size_t nr);

LIBLOG_HIDDEN struct android_log_transport_write pmsgLoggerWrite = {
    .node = { &pmsgLoggerWrite.node, &pmsgLoggerWrite.node },
    .context.fd = -1,
    .name = "pmsg",
    .available = pmsgAvailable,
    .open = pmsgOpen,
    .close = pmsgClose,
    .write = pmsgWrite,
};

static bool pmsgShouldUse = false;

// Only use pmsg on eng builds
static bool pmsgIsEng() {
    char buf[PROP_VALUE_MAX];

    if (__system_property_get("ro.build.type", buf) == 0) {
        return false;
    }

    if (!strncmp(buf, "eng", sizeof("eng"))) {
        return true;
    }
    return false;
}

static int pmsgOpen()
{
    pmsgShouldUse = pmsgIsEng();
    if (pmsgLoggerWrite.context.fd < 0) {
        pmsgLoggerWrite.context.fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
    }

    return pmsgLoggerWrite.context.fd;
}

static void pmsgClose()
{
    if (pmsgLoggerWrite.context.fd >= 0) {
        close(pmsgLoggerWrite.context.fd);
        pmsgLoggerWrite.context.fd = -1;
    }
}

static int pmsgAvailable(log_id_t logId)
{
    if (logId > LOG_ID_SECURITY) {
        return -EINVAL;
    }
    if ((logId != LOG_ID_SECURITY) &&
            (logId != LOG_ID_EVENTS) &&
            (!pmsgShouldUse || !__android_log_is_debuggable())) {
        return -EINVAL;
    }
    if (pmsgLoggerWrite.context.fd < 0) {
        if (access("/dev/pmsg0", W_OK) == 0) {
            return 0;
        }
        return -EBADF;
    }
    return 1;
}

/*
 * Extract a 4-byte value from a byte stream.
 */
static inline uint32_t get4LE(const uint8_t* src)
{
    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}

static int pmsgWrite(log_id_t logId, struct timespec *ts,
                      struct iovec *vec, size_t nr)
{
    static const unsigned headerLength = 2;
    struct iovec newVec[nr + headerLength];
    android_log_header_t header;
    android_pmsg_log_header_t pmsgHeader;
    size_t i, payloadSize;
    ssize_t ret;

    if ((logId == LOG_ID_EVENTS) && (!pmsgShouldUse || !__android_log_is_debuggable())) {
        if (vec[0].iov_len < 4) {
            return -EINVAL;
        }

        if (SNET_EVENT_LOG_TAG != get4LE(vec[0].iov_base)) {
            return -EPERM;
        }
    }

    if (pmsgLoggerWrite.context.fd < 0) {
        return -EBADF;
    }

    /*
     *  struct {
     *      // what we provide to pstore
     *      android_pmsg_log_header_t pmsgHeader;
     *      // what we provide to file
     *      android_log_header_t header;
     *      // caller provides
     *      union {
     *          struct {
     *              char     prio;
     *              char     payload[];
     *          } string;
     *          struct {
     *              uint32_t tag
     *              char     payload[];
     *          } binary;
     *      };
     *  };
     */

    pmsgHeader.magic = LOGGER_MAGIC;
    pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header);
    pmsgHeader.uid = __android_log_uid();
    pmsgHeader.pid = getpid();

    header.id = logId;
    header.tid = gettid();
    header.realtime.tv_sec = ts->tv_sec;
    header.realtime.tv_nsec = ts->tv_nsec;

    newVec[0].iov_base   = (unsigned char *)&pmsgHeader;
    newVec[0].iov_len    = sizeof(pmsgHeader);
    newVec[1].iov_base   = (unsigned char *)&header;
    newVec[1].iov_len    = sizeof(header);

    for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
        newVec[i].iov_base = vec[i - headerLength].iov_base;
        payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;

        if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
            newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
            if (newVec[i].iov_len) {
                ++i;
            }
            payloadSize = LOGGER_ENTRY_MAX_PAYLOAD;
            break;
        }
    }
    pmsgHeader.len += payloadSize;

    ret = TEMP_FAILURE_RETRY(writev(pmsgLoggerWrite.context.fd, newVec, i));
    if (ret < 0) {
        ret = errno ? -errno : -ENOTCONN;
    }

    if (ret > (ssize_t)(sizeof(header) + sizeof(pmsgHeader))) {
        ret -= sizeof(header) - sizeof(pmsgHeader);
    }

    return ret;
}

/*
 * Virtual pmsg filesystem
 *
 * Payload will comprise the string "<basedir>:<basefile>\0<content>" to a
 * maximum of LOGGER_ENTRY_MAX_PAYLOAD, but scaled to the last newline in the
 * file.
 *
 * Will hijack the header.realtime.tv_nsec field for a sequence number in usec.
 */

static inline const char *strnrchr(const char *buf, size_t len, char c) {
    const char *cp = buf + len;
    while ((--cp > buf) && (*cp != c));
    if (cp <= buf) {
        return buf + len;
    }
    return cp;
}

/* Write a buffer as filename references (tag = <basedir>:<basename>) */
LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write(
        log_id_t logId,
        char prio,
        const char *filename,
        const char *buf, size_t len) {
    int fd;
    size_t length, packet_len;
    const char *tag;
    char *cp, *slash;
    struct timespec ts;
    struct iovec vec[3];

    /* Make sure the logId value is not a bad idea */
    if ((logId == LOG_ID_KERNEL) ||       /* Verbotten */
            (logId == LOG_ID_EVENTS) ||   /* Do not support binary content */
            (logId == LOG_ID_SECURITY) || /* Bad idea to allow */
            ((unsigned)logId >= 32)) {    /* fit within logMask on arch32 */
        return -EINVAL;
    }

    clock_gettime(android_log_clockid(), &ts);

    cp = strdup(filename);
    if (!cp) {
        return -ENOMEM;
    }

    fd = pmsgLoggerWrite.context.fd;
    if (fd < 0) {
        __android_log_lock();
        fd = pmsgOpen();
        __android_log_unlock();
        if (fd < 0) {
            return -EBADF;
        }
    }

    tag = cp;
    slash = strrchr(cp, '/');
    if (slash) {
        *slash = ':';
        slash = strrchr(cp, '/');
        if (slash) {
            tag = slash + 1;
        }
    }

    length = strlen(tag) + 1;
    packet_len = LOGGER_ENTRY_MAX_PAYLOAD - sizeof(char) - length;

    vec[0].iov_base = &prio;
    vec[0].iov_len  = sizeof(char);
    vec[1].iov_base = (unsigned char *)tag;
    vec[1].iov_len  = length;

    for (ts.tv_nsec = 0, length = len;
            length;
            ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) {
        ssize_t ret;
        size_t transfer;

        if ((ts.tv_nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=
                ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) {
            len -= length;
            break;
        }

        transfer = length;
        if (transfer > packet_len) {
            transfer = strnrchr(buf, packet_len - 1, '\n') - buf;
            if ((transfer < length) && (buf[transfer] == '\n')) {
                ++transfer;
            }
        }

        vec[2].iov_base = (unsigned char *)buf;
        vec[2].iov_len  = transfer;

        ret = pmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0]));

        if (ret <= 0) {
            free(cp);
            return ret;
        }
        length -= transfer;
        buf += transfer;
    }
    free(cp);
    return len;
}
