/* commands/sysloader/installer/installer.c
 *
 * Copyright 2008, 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.
 */

#define LOG_TAG "installer"

#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>


#include <cutils/config_utils.h>
#include <cutils/log.h>

#include "diskconfig/diskconfig.h"
#include "installer.h"

#define MKE2FS_BIN     "/system/bin/mke2fs"
#define E2FSCK_BIN     "/system/bin/e2fsck"
#define TUNE2FS_BIN    "/system/bin/tune2fs"
#define RESIZE2FS_BIN  "/system/bin/resize2fs"

static int
usage(void)
{
    fprintf(stderr, "Usage: %s\n", LOG_TAG);
    fprintf(stderr, "\t-c <path> - Path to installer conf file "
                    "(/system/etc/installer.conf)\n");
    fprintf(stderr, "\t-l <path> - Path to device disk layout conf file "
                    "(/system/etc/disk_layout.conf)\n");
    fprintf(stderr, "\t-h        - This help message\n");
    fprintf(stderr, "\t-d        - Dump the compiled in partition info.\n");
    fprintf(stderr, "\t-p <path> - Path to device that should be mounted"
                    " to /data.\n");
    fprintf(stderr, "\t-t        - Test mode. Don't write anything to disk.\n");
    return 1;
}

static cnode *
read_conf_file(const char *fn)
{
    cnode *root = config_node("", "");
    config_load_file(root, fn);

    if (root->first_child == NULL) {
        LOGE("Could not read config file %s", fn);
        return NULL;
    }

    return root;
}

static int
exec_cmd(const char *cmd, ...) /* const char *arg, ...) */
{
    va_list ap;
    int size = 0;
    char *str;
    char *outbuf;
    int rv;

    /* compute the size for the command buffer */
    size = strlen(cmd) + 1;
    va_start(ap, cmd);
    while ((str = va_arg(ap, char *))) {
        size += strlen(str) + 1;  /* need room for the space separator */
    }
    va_end(ap);

    if (!(outbuf = malloc(size + 1))) {
        LOGE("Can't allocate memory to exec cmd");
        return -1;
    }

    /* this is a bit inefficient, but is trivial, and works */
    strcpy(outbuf, cmd);
    va_start(ap, cmd);
    while ((str = va_arg(ap, char *))) {
        strcat(outbuf, " ");
        strcat(outbuf, str);
    }
    va_end(ap);

    LOGI("Executing: %s", outbuf);
    rv = system(outbuf);
    free(outbuf);
    if (rv < 0) {
        LOGI("Error while trying to execute '%s'", cmd);
        return -1;
    }
    rv = WEXITSTATUS(rv);
    LOGI("Done executing %s (%d)", outbuf, rv);
    return rv;
}


static int
do_fsck(const char *dst, int force)
{
    int rv;
    const char *opts = force ? "-fy" : "-y";


    LOGI("Running e2fsck... (force=%d) This MAY take a while.", force);
    if ((rv = exec_cmd(E2FSCK_BIN, "-C 0", opts, dst, NULL)) < 0)
        return 1;
    if (rv >= 4) {
        LOGE("Error while running e2fsck: %d", rv);
        return 1;
    }
    sync();
    LOGI("e2fsck succeeded (exit code: %d)", rv);

    return 0;
}

static int
process_ext2_image(const char *dst, const char *src, uint32_t flags, int test)
{
    int rv;

    /* First, write the image to disk. */
    if (write_raw_image(dst, src, 0, test))
        return 1;

    if (test)
        return 0;

    /* Next, let's e2fsck the fs to make sure it got written ok, and
     * everything is peachy */
    if (do_fsck(dst, 1))
        return 1;

    /* set the mount count to 1 so that 1st mount on boot doesn't complain */
    if ((rv = exec_cmd(TUNE2FS_BIN, "-C", "1", dst, NULL)) < 0)
        return 1;
    if (rv) {
        LOGE("Error while running tune2fs: %d", rv);
        return 1;
    }

    /* If the user requested that we resize, let's do it now */
    if (flags & INSTALL_FLAG_RESIZE) {
        if ((rv = exec_cmd(RESIZE2FS_BIN, "-F", dst, NULL)) < 0)
            return 1;
        if (rv) {
            LOGE("Error while running resize2fs: %d", rv);
            return 1;
        }
        sync();
        if (do_fsck(dst, 0))
            return 1;
    }

    /* make this an ext3 fs? */
    if (flags & INSTALL_FLAG_ADDJOURNAL) {
        if ((rv = exec_cmd(TUNE2FS_BIN, "-j", dst, NULL)) < 0)
            return 1;
        if (rv) {
            LOGE("Error while running tune2fs: %d", rv);
            return 1;
        }
        sync();
        if (do_fsck(dst, 0))
            return 1;
    }

    return 0;
}


/* TODO: PLEASE break up this function into several functions that just
 * do what they need with the image node. Many of them will end up
 * looking at same strings, but it will be sooo much cleaner */
static int
process_image_node(cnode *img, struct disk_info *dinfo, int test)
{
    struct part_info *pinfo = NULL;
    loff_t offset = (loff_t)-1;
    const char *filename = NULL;
    char *dest_part = NULL;
    const char *tmp;
    uint32_t flags = 0;
    uint8_t type = 0;
    int rv;
    int func_ret = 1;

    filename = config_str(img, "filename", NULL);

    /* process the 'offset' image parameter */
    if ((tmp = config_str(img, "offset", NULL)) != NULL)
        offset = strtoull(tmp, NULL, 0);

    /* process the 'partition' image parameter */
    if ((tmp = config_str(img, "partition", NULL)) != NULL) {
        if (offset != (loff_t)-1) {
            LOGE("Cannot specify the partition name AND an offset for %s",
                 img->name);
            goto fail;
        }

        if (!(pinfo = find_part(dinfo, tmp))) {
            LOGE("Cannot find partition %s while processing %s",
                 tmp, img->name);
            goto fail;
        }

        if (!(dest_part = find_part_device(dinfo, pinfo->name))) {
            LOGE("Could not get the device name for partition %s while"
                 " processing image %s", pinfo->name, img->name);
            goto fail;
        }
        offset = pinfo->start_lba * dinfo->sect_size;
    }

    /* process the 'mkfs' parameter */
    if ((tmp = config_str(img, "mkfs", NULL)) != NULL) {
        char *journal_opts;
        char vol_lbl[16]; /* ext2/3 has a 16-char volume label */

        if (!pinfo) {
            LOGE("Target partition required for mkfs for '%s'", img->name);
            goto fail;
        } else if (filename) {
            LOGE("Providing filename and mkfs parameters is meaningless");
            goto fail;
        }

        if (!strcmp(tmp, "ext4"))
            journal_opts = "";
        else if (!strcmp(tmp, "ext2"))
            journal_opts = "";
        else if (!strcmp(tmp, "ext3"))
            journal_opts = "-j";
        else {
            LOGE("Unknown filesystem type for mkfs: %s", tmp);
            goto fail;
        }

        /* put the partition name as the volume label */
        strncpy(vol_lbl, pinfo->name, sizeof(vol_lbl));

        /* since everything checked out, lets make the fs, and return since
         * we don't need to do anything else */
        rv = exec_cmd(MKE2FS_BIN, "-L", vol_lbl, journal_opts, dest_part, NULL);
        if (rv < 0)
            goto fail;
        else if (rv > 0) {
            LOGE("Error while running mke2fs: %d", rv);
            goto fail;
        }
        sync();
        if (do_fsck(dest_part, 0))
            goto fail;
        goto done;
    }

    /* since we didn't mkfs above, all the rest of the options assume
     * there's a filename involved */
    if (!filename) {
        LOGE("Filename is required for image %s", img->name);
        goto fail;
    }

    /* process the 'flags' image parameter */
    if ((tmp = config_str(img, "flags", NULL)) != NULL) {
        char *flagstr, *flagstr_orig;

        if (!(flagstr = flagstr_orig = strdup(tmp))) {
            LOGE("Cannot allocate memory for dup'd flags string");
            goto fail;
        }
        while ((tmp = strsep(&flagstr, ","))) {
            if (!strcmp(tmp, "resize"))
                flags |= INSTALL_FLAG_RESIZE;
            else if (!strcmp(tmp, "addjournal"))
                flags |= INSTALL_FLAG_ADDJOURNAL;
            else {
                LOGE("Unknown flag '%s' for image %s", tmp, img->name);
                free(flagstr_orig);
                goto fail;
            }
        }
        free(flagstr_orig);
    }

    /* process the 'type' image parameter */
    if (!(tmp = config_str(img, "type", NULL))) {
        LOGE("Type is required for image %s", img->name);
        goto fail;
    } else if (!strcmp(tmp, "raw")) {
        type = INSTALL_IMAGE_RAW;
    } else if (!strcmp(tmp, "ext2")) {
        type = INSTALL_IMAGE_EXT2;
    } else if (!strcmp(tmp, "ext3")) {
        type = INSTALL_IMAGE_EXT3;
    } else if (!strcmp(tmp, "ext4")) {
        type = INSTALL_IMAGE_EXT4;
    } else {
        LOGE("Unknown image type '%s' for image %s", tmp, img->name);
        goto fail;
    }

    /* at this point we MUST either have a partition in 'pinfo' or a raw
     * 'offset', otherwise quit */
    if (!pinfo && (offset == (loff_t)-1)) {
        LOGE("Offset to write into the disk is unknown for %s", img->name);
        goto fail;
    }

    if (!pinfo && (type != INSTALL_IMAGE_RAW)) {
        LOGE("Only raw images can specify direct offset on the disk. Please"
             " specify the target partition name instead. (%s)", img->name);
        goto fail;
    }

    switch(type) {
        case INSTALL_IMAGE_RAW:
            if (write_raw_image(dinfo->device, filename, offset, test))
                goto fail;
            break;

        case INSTALL_IMAGE_EXT3:
            /* makes the error checking in the imager function easier */
            if (flags & INSTALL_FLAG_ADDJOURNAL) {
                LOGW("addjournal flag is meaningless for ext3 images");
                flags &= ~INSTALL_FLAG_ADDJOURNAL;
            }
            /* ...fall through... */

        case INSTALL_IMAGE_EXT4:
            /* fallthru */

        case INSTALL_IMAGE_EXT2:
            if (process_ext2_image(dest_part, filename, flags, test))
                goto fail;
            break;

        default:
            LOGE("Unknown image type: %d", type);
            goto fail;
    }

done:
    func_ret = 0;

fail:
    if (dest_part)
        free(dest_part);
    return func_ret;
}

int
main(int argc, char *argv[])
{
    char *disk_conf_file = "/system/etc/disk_layout.conf";
    char *inst_conf_file = "/system/etc/installer.conf";
    char *inst_data_dir = "/data";
    char *inst_data_dev = NULL;
    char *data_fstype = "ext4";
    cnode *config;
    cnode *images;
    cnode *img;
    int cnt = 0;
    struct disk_info *device_disk_info;
    int dump = 0;
    int test = 0;
    int x;

    while ((x = getopt (argc, argv, "thdc:l:p:")) != EOF) {
        switch (x) {
            case 'h':
                return usage();
            case 'c':
                inst_conf_file = optarg;
                break;
            case 'l':
                disk_conf_file = optarg;
                break;
            case 't':
                test = 1;
                break;
            case 'p':
                inst_data_dev = optarg;
                break;
            case 'd':
                dump = 1;
                break;
            default:
                fprintf(stderr, "Unknown argument: %c\n", (char)optopt);
                return usage();
        }
    }

    /* If the user asked us to wait for data device, wait for it to appear,
     * and then mount it onto /data */
    if (inst_data_dev && !dump) {
        struct stat filestat;

        LOGI("Waiting for device: %s", inst_data_dev);
        while (stat(inst_data_dev, &filestat))
            sleep(1);
        LOGI("Device %s ready", inst_data_dev);
        if (mount(inst_data_dev, inst_data_dir, data_fstype, MS_RDONLY, NULL)) {
            LOGE("Could not mount %s on %s as %s", inst_data_dev, inst_data_dir,
                 data_fstype);
            return 1;
        }
    }

    /* Read and process the disk configuration */
    if (!(device_disk_info = load_diskconfig(disk_conf_file, NULL))) {
        LOGE("Errors encountered while loading disk conf file %s",
             disk_conf_file);
        return 1;
    }

    if (process_disk_config(device_disk_info)) {
        LOGE("Errors encountered while processing disk config from %s",
             disk_conf_file);
        return 1;
    }

    /* Was all of this for educational purposes? If so, quit. */
    if (dump) {
        dump_disk_config(device_disk_info);
        return 0;
    }

    /* This doesnt do anything but load the config file */
    if (!(config = read_conf_file(inst_conf_file)))
        return 1;

    /* First, partition the drive */
    if (apply_disk_config(device_disk_info, test))
        return 1;

    /* Now process the installer config file and write the images to disk */
    if (!(images = config_find(config, "images"))) {
        LOGE("Invalid configuration file %s. Missing 'images' section",
             inst_conf_file);
        return 1;
    }

    for (img = images->first_child; img; img = img->next) {
        if (process_image_node(img, device_disk_info, test)) {
            LOGE("Unable to write data to partition. Try running 'installer' again.");
            return 1;
        }
        ++cnt;
    }

    /*
     * We have to do the apply() twice. We must do it once before the image
     * writes to layout the disk partitions so that we can write images to
     * them. We then do the apply() again in case one of the images
     * replaced the MBR with a new bootloader, and thus messed with
     * partition table.
     */
    if (apply_disk_config(device_disk_info, test))
        return 1;

    LOGI("Done processing installer config. Configured %d images", cnt);
    LOGI("Type 'reboot' or reset to run new image");
    return 0;
}
