/*
 * 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 <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

#include <private/android_filesystem_config.h>
#include <private/android_logger.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 int pmsgOpen() {
  int fd = atomic_load(&pmsgLoggerWrite.context.fd);
  if (fd < 0) {
    int i;

    fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
    i = atomic_exchange(&pmsgLoggerWrite.context.fd, fd);
    if ((i >= 0) && (i != fd)) {
      close(i);
    }
  }

  return fd;
}

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

static int pmsgAvailable(log_id_t logId) {
  if (logId > LOG_ID_SECURITY) {
    return -EINVAL;
  }
  if ((logId != LOG_ID_SECURITY) && (logId != LOG_ID_EVENTS) &&
      !__android_log_is_debuggable()) {
    return -EINVAL;
  }
  if (atomic_load(&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) && !__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 (atomic_load(&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(atomic_load(&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) {
  bool weOpened;
  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;
  }

  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;

  weOpened = false;
  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;

    if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
      if (!weOpened) { /* Impossible for weOpened = true here */
        __android_log_lock();
      }
      weOpened = atomic_load(&pmsgLoggerWrite.context.fd) < 0;
      if (!weOpened) {
        __android_log_unlock();
      } else if (pmsgOpen() < 0) {
        __android_log_unlock();
        free(cp);
        return -EBADF;
      }
    }

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

    if (ret <= 0) {
      if (weOpened) {
        pmsgClose();
        __android_log_unlock();
      }
      free(cp);
      return ret ? ret : (len - length);
    }
    length -= transfer;
    buf += transfer;
  }
  if (weOpened) {
    pmsgClose();
    __android_log_unlock();
  }
  free(cp);
  return len;
}
