1 /* tools/editdisklbl/editdisklbl.c
3 * Copyright 2008, The Android Open Source Project
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #define __USE_LARGEFILE64
19 #define __USE_FILE_OFFSET64
27 #include <sys/types.h>
29 #include "diskconfig/diskconfig.h"
31 /* give us some room */
32 #define EXTRA_LBAS 100
34 static struct pf_map {
35 struct part_info *pinfo;
37 } part_file_map[MAX_NUM_PARTS] = { {0, 0} };
43 "\nusage: editdisklbl <options> part1=file1 [part2=file2,...]\n"
44 "Where options can be one of:\n"
45 "\t\t-l <layout conf> -- The image layout config file.\n"
46 "\t\t-i <image file> -- The image file to edit.\n"
47 "\t\t-t -- Test mode (optional)\n"
48 "\t\t-v -- Be verbose\n"
49 "\t\t-h -- This message (optional)\n"
55 parse_args(int argc, char *argv[], struct disk_info **dinfo, int *test,
58 char *layout_conf = NULL;
59 char *img_file = NULL;
64 while ((x = getopt (argc, argv, "vthl:i:")) != EOF) {
81 fprintf(stderr, "Unknown argument: %c\n", (char)optopt);
86 if (!img_file || !layout_conf) {
87 fprintf(stderr, "Image filename and configuration file are required\n");
91 /* we'll need to parse the command line later for partition-file
92 * mappings, so make sure there's at least something there */
94 fprintf(stderr, "Must provide partition -> file mappings\n");
98 if (stat(img_file, &filestat)) {
99 perror("Cannot stat image file");
103 /* make sure we don't screw up and write to a block device on the host
104 * and wedge things. I just don't trust myself. */
105 if (!S_ISREG(filestat.st_mode)) {
106 fprintf(stderr, "This program should only be used on regular files.");
110 /* load the disk layout file */
111 if (!(*dinfo = load_diskconfig(layout_conf, img_file))) {
112 fprintf(stderr, "Errors encountered while loading disk conf file %s",
117 if ((*dinfo)->num_lba == 0) {
118 (*dinfo)->num_lba = (*dinfo)->skip_lba + EXTRA_LBAS;
122 /* parse the filename->partition mappings from the command line and patch
123 * up a loaded config file's partition table entries to have
124 * length == filesize */
126 while (optind < argc) {
127 char *pair = argv[optind++];
129 struct part_info *pinfo;
130 struct stat tmp_stat;
132 if (x >= MAX_NUM_PARTS) {
133 fprintf(stderr, "Error: Too many partitions specified (%d)!\n", x);
137 if (!(part_name = strsep(&pair, "=")) || !pair || !(*pair)) {
138 fprintf(stderr, "Error parsing partition mappings\n");
142 if (!(pinfo = find_part(*dinfo, part_name))) {
143 fprintf(stderr, "Partition '%s' not found.\n", part_name);
147 /* here pair points to the filename (after the '=') */
148 part_file_map[x].pinfo = pinfo;
149 part_file_map[x++].filename = pair;
151 if (stat(pair, &tmp_stat) < 0) {
152 fprintf(stderr, "Could not stat file: %s\n", pair);
156 pinfo->len_kb = (uint32_t) ((tmp_stat.st_size + 1023) >> 10);
159 ((uint64_t)pinfo->len_kb * 1024) / (*dinfo)->sect_size;
160 printf("Updated %s length to be %uKB\n", pinfo->name, pinfo->len_kb);
167 main(int argc, char *argv[])
169 struct disk_info *dinfo = NULL;
174 if (parse_args(argc, argv, &dinfo, &test, &verbose))
178 dump_disk_config(dinfo);
181 printf("Test mode enabled. Actions will not be committed to disk!\n");
183 if (apply_disk_config(dinfo, test)) {
184 fprintf(stderr, "Could not apply disk configuration!\n");
188 printf("Copying images to specified partition offsets\n");
189 /* now copy the images to their appropriate locations on disk */
190 for (cnt = 0; cnt < MAX_NUM_PARTS && part_file_map[cnt].pinfo; ++cnt) {
191 loff_t offs = part_file_map[cnt].pinfo->start_lba * dinfo->sect_size;
192 const char *dest_fn = dinfo->device;
193 if (write_raw_image(dest_fn, part_file_map[cnt].filename, offs, test)) {
194 fprintf(stderr, "Could not write images after editing label.\n");
198 printf("File edit complete. Wrote %d images.\n", cnt);