/* tools/editdisklbl/editdisklbl.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 __USE_LARGEFILE64
#define __USE_FILE_OFFSET64
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "diskconfig.h"

/* give us some room */
#define EXTRA_LBAS      100

static struct pf_map {
    struct part_info *pinfo;
    const char *filename;
} part_file_map[MAX_NUM_PARTS] = { {0, 0} };

static int
usage(void)
{
    fprintf(stderr,
            "\nusage: editdisklbl <options> part1=file1 [part2=file2,...]\n"
            "Where options can be one of:\n"
            "\t\t-l <layout conf>  -- The image layout config file.\n"
            "\t\t-i <image file>   -- The image file to edit.\n"
            "\t\t-t                -- Test mode (optional)\n"
            "\t\t-v                -- Be verbose\n"
            "\t\t-h                -- This message (optional)\n"
            );
    return 1;
}

static int
parse_args(int argc, char *argv[], struct disk_info **dinfo, int *test,
           int *verbose)
{
    char *layout_conf = NULL;
    char *img_file = NULL;
    struct stat filestat;
    int x;
    int update_lba = 0;

    while ((x = getopt (argc, argv, "vthl:i:")) != EOF) {
        switch (x) {
            case 'h':
                return usage();
            case 'l':
                layout_conf = optarg;
                break;
            case 't':
                *test = 1;
                break;
            case 'i':
                img_file = optarg;
                break;
            case 'v':
                *verbose = 1;
                break;
            default:
                fprintf(stderr, "Unknown argument: %c\n", (char)optopt);
                return usage();
        }
    }

    if (!img_file || !layout_conf) {
        fprintf(stderr, "Image filename and configuration file are required\n");
        return usage();
    }

    /* we'll need to parse the command line later for partition-file
     * mappings, so make sure there's at least something there */
    if (optind >= argc) {
        fprintf(stderr, "Must provide partition -> file mappings\n");
        return usage();
    }

    if (stat(img_file, &filestat)) {
        perror("Cannot stat image file");
        return 1;
    }

    /* make sure we don't screw up and write to a block device on the host
     * and wedge things. I just don't trust myself. */
    if (!S_ISREG(filestat.st_mode)) {
        fprintf(stderr, "This program should only be used on regular files.");
        return 1;
    }

    /* load the disk layout file */
    if (!(*dinfo = load_diskconfig(layout_conf, img_file))) {
        fprintf(stderr, "Errors encountered while loading disk conf file %s",
                layout_conf);
        return 1;
    }

    if ((*dinfo)->num_lba == 0) {
        (*dinfo)->num_lba = (*dinfo)->skip_lba + EXTRA_LBAS;
        update_lba = 1;
    }

    /* parse the filename->partition mappings from the command line and patch
     * up a loaded config file's partition table entries to have
     * length == filesize */
    x = 0;
    while (optind < argc) {
        char *pair = argv[optind++];
        char *part_name;
        struct part_info *pinfo;
        struct stat tmp_stat;

        if (x >= MAX_NUM_PARTS) {
            fprintf(stderr, "Error: Too many partitions specified (%d)!\n", x);
            return 1;
        }

        if (!(part_name = strsep(&pair, "=")) || !pair || !(*pair)) {
            fprintf(stderr, "Error parsing partition mappings\n");
            return usage();
        }

        if (!(pinfo = find_part(*dinfo, part_name))) {
            fprintf(stderr, "Partition '%s' not found.\n", part_name);
            return 1;
        }

        /* here pair points to the filename (after the '=') */
        part_file_map[x].pinfo = pinfo;
        part_file_map[x++].filename = pair;

        if (stat(pair, &tmp_stat) < 0) {
            fprintf(stderr, "Could not stat file: %s\n", pair);
            return 1;
        }

        pinfo->len_kb = (uint32_t) ((tmp_stat.st_size + 1023) >> 10);
        if (update_lba)
            (*dinfo)->num_lba += 
                    ((uint64_t)pinfo->len_kb * 1024) / (*dinfo)->sect_size;
        printf("Updated %s length to be %uKB\n", pinfo->name, pinfo->len_kb);
    }

    return 0;
}

int
main(int argc, char *argv[])
{
    struct disk_info *dinfo = NULL;
    int test = 0;
    int verbose = 0;
    int cnt;

    if (parse_args(argc, argv, &dinfo, &test, &verbose))
        return 1;

    if (verbose)
        dump_disk_config(dinfo);

    if (test)
        printf("Test mode enabled. Actions will not be committed to disk!\n");

    if (apply_disk_config(dinfo, test)) {
        fprintf(stderr, "Could not apply disk configuration!\n");
        return 1;
    }

    printf("Copying images to specified partition offsets\n");
    /* now copy the images to their appropriate locations on disk */
    for (cnt = 0; cnt < MAX_NUM_PARTS && part_file_map[cnt].pinfo; ++cnt) {
        loff_t offs = part_file_map[cnt].pinfo->start_lba * dinfo->sect_size;
        const char *dest_fn = dinfo->device;
        if (write_raw_image(dest_fn, part_file_map[cnt].filename, offs, test)) {
            fprintf(stderr, "Could not write images after editing label.\n");
            return 1;
        }
    }
    printf("File edit complete. Wrote %d images.\n", cnt);

    return 0;
}
