/* 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.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, "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 {
        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_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 = "ext2";
    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;
}
