+++ /dev/null
-/* 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/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;
-}