/*
 * Copyright (C) 2015 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.
 */


#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <cutils/properties.h>

#include <bootloader.h>
#include <fs_mgr.h>

#include "bootinfo.h"

// Open the appropriate fstab file and fallback to /fstab.device if
// that's what's being used.
static struct fstab *open_fstab(void)
{
  char propbuf[PROPERTY_VALUE_MAX];
  char fstab_name[PROPERTY_VALUE_MAX + 32];
  struct fstab *fstab;

  property_get("ro.hardware", propbuf, "");
  snprintf(fstab_name, sizeof(fstab_name), "/fstab.%s", propbuf);
  fstab = fs_mgr_read_fstab(fstab_name);
  if (fstab != NULL)
    return fstab;

  fstab = fs_mgr_read_fstab("/fstab.device");
  return fstab;
}

int boot_info_open_partition(const char *name, uint64_t *out_size, int flags)
{
  char *path;
  int fd;
  struct fstab *fstab;
  struct fstab_rec *record;

  // We can't use fs_mgr to look up |name| because fstab doesn't list
  // every slot partition (it uses the slotselect option to mask the
  // suffix) and |slot| is expected to be of that form, e.g. boot_a.
  //
  // We can however assume that there's an entry for the /misc mount
  // point and use that to get the device file for the misc
  // partition. From there we'll assume that a by-name scheme is used
  // so we can just replace the trailing "misc" by the given |name|,
  // e.g.
  //
  //   /dev/block/platform/soc.0/7824900.sdhci/by-name/misc ->
  //   /dev/block/platform/soc.0/7824900.sdhci/by-name/boot_a
  //
  // If needed, it's possible to relax this assumption in the future
  // by trawling /sys/block looking for the appropriate sibling of
  // misc and then finding an entry in /dev matching the sysfs entry.

  fstab = open_fstab();
  if (fstab == NULL)
    return -1;
  record = fs_mgr_get_entry_for_mount_point(fstab, "/misc");
  if (record == NULL) {
    fs_mgr_free_fstab(fstab);
    return -1;
  }
  if (strcmp(name, "misc") == 0) {
    path = strdup(record->blk_device);
  } else {
    size_t trimmed_len, name_len;
    const char *end_slash = strrchr(record->blk_device, '/');
    if (end_slash == NULL) {
      fs_mgr_free_fstab(fstab);
      return -1;
    }
    trimmed_len = end_slash - record->blk_device + 1;
    name_len = strlen(name);
    path = calloc(trimmed_len + name_len + 1, 1);
    strncpy(path, record->blk_device, trimmed_len);
    strncpy(path + trimmed_len, name, name_len);
  }
  fs_mgr_free_fstab(fstab);

  fd = open(path, flags);
  free(path);

  // If we successfully opened the device, get size if requested.
  if (fd != -1 && out_size != NULL) {
    if (ioctl(fd, BLKGETSIZE64, out_size) != 0) {
      close(fd);
      return -1;
    }
  }

  return fd;
}

// As per struct bootloader_message_ab which is defined in
// bootable/recovery/bootloader.h we can use the 32 bytes in the
// bootctrl_suffix field provided that they start with the active slot
// suffix terminated by NUL. It just so happens that BrilloBootInfo is
// laid out this way.
#define BOOTINFO_OFFSET offsetof(struct bootloader_message_ab, slot_suffix)

bool boot_info_load(BrilloBootInfo *out_info)
{
  int fd;

  memset(out_info, '\0', sizeof(BrilloBootInfo));

  fd = boot_info_open_partition("misc", NULL, O_RDONLY);
  if (fd == -1)
    return false;
  if (lseek(fd, BOOTINFO_OFFSET, SEEK_SET) != BOOTINFO_OFFSET) {
    close(fd);
    return false;
  }
  ssize_t num_read;
  do {
    num_read = read(fd, (void*) out_info, sizeof(BrilloBootInfo));
  } while (num_read == -1 && errno == EINTR);
  close(fd);
  if (num_read != sizeof(BrilloBootInfo))
    return false;
  return true;
}

bool boot_info_save(BrilloBootInfo *info)
{
  int fd;

  fd = boot_info_open_partition("misc", NULL, O_RDWR);
  if (fd == -1)
    return false;
  if (lseek(fd, BOOTINFO_OFFSET, SEEK_SET) != BOOTINFO_OFFSET) {
    close(fd);
    return false;
  }
  ssize_t num_written;
  do {
    num_written = write(fd, (void*) info, sizeof(BrilloBootInfo));
  } while (num_written == -1 && errno == EINTR);
  close(fd);
  if (num_written != sizeof(BrilloBootInfo))
    return false;
  return true;
}

bool boot_info_validate(BrilloBootInfo* info)
{
  if (info->magic[0] != 'B' ||
      info->magic[1] != 'C' ||
      info->magic[2] != 'c')
    return false;
  if (info->active_slot >= 2)
    return false;
  return true;
}

void boot_info_reset(BrilloBootInfo* info)
{
  memset(info, '\0', sizeof(BrilloBootInfo));
  info->magic[0] = 'B';
  info->magic[1] = 'C';
  info->magic[2] = 'c';
}
