ext2simg.c revision dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7
1a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross/* 2a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * Copyright (C) 2010 The Android Open Source Project 3a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * 4a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 5a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * you may not use this file except in compliance with the License. 6a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * You may obtain a copy of the License at 7a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * 8a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * http://www.apache.org/licenses/LICENSE-2.0 9a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * 10a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * Unless required by applicable law or agreed to in writing, software 11a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * distributed under the License is distributed on an "AS IS" BASIS, 12a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * See the License for the specific language governing permissions and 14a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross * limitations under the License. 15a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross */ 16a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 17dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross#include <sparse/sparse.h> 18dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross 19a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include "ext4_utils.h" 20a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include "make_ext4fs.h" 21a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include "allocate.h" 22a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 23a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include <sys/types.h> 24a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include <sys/stat.h> 25a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include <sys/types.h> 26a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include <sys/mman.h> 27a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include <fcntl.h> 28a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include <libgen.h> 29a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross#include <unistd.h> 30a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 310349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau#ifndef USE_MINGW /* O_BINARY is windows-specific flag */ 320349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau#define O_BINARY 0 330349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau#endif 340349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau 35a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Crossextern struct fs_info info; 36a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 37a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Crossstatic int verbose = 0; 38a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 39a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Crossstatic void usage(char *path) 40a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross{ 41a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, "%s [ options ] <image or block device> <output image>\n", path); 42a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, "\n"); 43a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, " -c include CRC block\n"); 44a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, " -v verbose output\n"); 45a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, " -z gzip output\n"); 46a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, " -S don't use sparse output format\n"); 47a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross} 48a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 49a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Crossstatic int read_ext(int fd) 50a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross{ 51a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross off64_t ret; 52a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross struct ext4_super_block sb; 53a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross unsigned int i; 54a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 55a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ret = lseek64(fd, 1024, SEEK_SET); 56a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret < 0) 57a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to seek to superblock"); 58a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 59a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ret = read(fd, &sb, sizeof(sb)); 60a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret < 0) 61a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to read superblock"); 62a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret != sizeof(sb)) 63a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error("failed to read all of superblock"); 64a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 65a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ext4_parse_sb(&sb); 66a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 67a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ret = lseek64(fd, info.len, SEEK_SET); 68a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret < 0) 69a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to seek to end of input image"); 70a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 71a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ret = lseek64(fd, info.block_size * (aux_info.first_data_block + 1), SEEK_SET); 72a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret < 0) 73a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to seek to block group descriptors"); 74a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 75a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ret = read(fd, aux_info.bg_desc, info.block_size * aux_info.bg_desc_blocks); 76a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret < 0) 77a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to read block group descriptors"); 78a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret != (int)info.block_size * (int)aux_info.bg_desc_blocks) 79a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error("failed to read all of block group descriptors"); 80a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 81a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (verbose) { 82a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf("Found filesystem with parameters:\n"); 83a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Size: %llu\n", info.len); 84a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Block size: %d\n", info.block_size); 85a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Blocks per group: %d\n", info.blocks_per_group); 86a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Inodes per group: %d\n", info.inodes_per_group); 87a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Inode size: %d\n", info.inode_size); 88a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Label: %s\n", info.label); 89a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Blocks: %llu\n", aux_info.len_blocks); 90a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Block groups: %d\n", aux_info.groups); 91a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Reserved block group size: %d\n", info.bg_desc_reserve_blocks); 92a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross printf(" Used %d/%d inodes and %d/%d blocks\n", 93a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count, 94a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross aux_info.sb->s_inodes_count, 95a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo, 96a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross aux_info.sb->s_blocks_count_lo); 97a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 98a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 99a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross return 0; 100a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross} 101a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 102a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Crossstatic int bitmap_get_bit(u8 *bitmap, u32 bit) 103a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross{ 104a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (bitmap[bit / 8] & 1 << (bit % 8)) 105a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross return 1; 106a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 107a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross return 0; 108a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross} 109a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 110a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Crossstatic int build_sparse_ext(int fd, const char *filename) 111a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross{ 112a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross unsigned int i; 113a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross unsigned int block; 114a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross int start_contiguous_block; 115a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross u8 *block_bitmap; 116a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross off64_t ret; 117a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 118a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross block_bitmap = malloc(info.block_size); 119a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (!block_bitmap) 120a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error("failed to allocate block bitmap"); 121a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 122a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (aux_info.first_data_block > 0) 123a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross queue_data_file(filename, 0, 124a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross info.block_size * aux_info.first_data_block, 0); 125a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 126a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross for (i = 0; i < aux_info.groups; i++) { 127a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross u32 first_block = aux_info.first_data_block + i * info.blocks_per_group; 128a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross u32 last_block = min(info.blocks_per_group, aux_info.len_blocks - first_block); 129a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 130a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ret = lseek64(fd, (u64)info.block_size * aux_info.bg_desc[i].bg_block_bitmap, 131a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross SEEK_SET); 132a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret < 0) 133a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to seek to block group bitmap %d", i); 134a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 135a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross ret = read(fd, block_bitmap, info.block_size); 136a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret < 0) 137a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to read block group bitmap %d", i); 138a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (ret != (int)info.block_size) 139a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error("failed to read all of block group bitmap %d", i); 140a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 141a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross start_contiguous_block = -1; 142a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross for (block = 0; block < last_block; block++) { 143a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (start_contiguous_block >= 0) { 144a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (!bitmap_get_bit(block_bitmap, block)) { 145a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross u32 start_block = first_block + start_contiguous_block; 146a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross u32 len_blocks = block - start_contiguous_block; 147a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 148a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross queue_data_file(filename, (u64)info.block_size * start_block, 149a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross info.block_size * len_blocks, start_block); 150a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross start_contiguous_block = -1; 151a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 152a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } else { 153a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (bitmap_get_bit(block_bitmap, block)) 154a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross start_contiguous_block = block; 155a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 156a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 157a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 158a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (start_contiguous_block >= 0) { 159a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross u32 start_block = first_block + start_contiguous_block; 160a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross u32 len_blocks = last_block - start_contiguous_block; 161a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross queue_data_file(filename, (u64)info.block_size * start_block, 162a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross info.block_size * len_blocks, start_block); 163a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 164a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 165a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 166a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross return 0; 167a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross} 168a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 169a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Crossint main(int argc, char **argv) 170a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross{ 171a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross int opt; 172a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross const char *in = NULL; 173a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross const char *out = NULL; 174a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross int gzip = 0; 175a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross int sparse = 1; 1760349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau int infd, outfd; 177a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross int crc = 0; 178a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 179a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross while ((opt = getopt(argc, argv, "cvzS")) != -1) { 180a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross switch (opt) { 181a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross case 'c': 182a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross crc = 1; 183a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross break; 184a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross case 'v': 185a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross verbose = 1; 186a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross break; 187a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross case 'z': 188a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross gzip = 1; 189a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross break; 190a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross case 'S': 191a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross sparse = 0; 192a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross break; 193a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 194a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 195a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 196a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (optind >= argc) { 197a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, "Expected image or block device after options\n"); 198a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross usage(argv[0]); 199a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross exit(EXIT_FAILURE); 200a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 201a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 202a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross in = argv[optind++]; 203a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 204a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (optind >= argc) { 205a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, "Expected output image after input image\n"); 206a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross usage(argv[0]); 207a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross exit(EXIT_FAILURE); 208a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 209a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 210a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross out = argv[optind++]; 211a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 212a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross if (optind < argc) { 213a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross fprintf(stderr, "Unexpected argument: %s\n", argv[optind]); 214a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross usage(argv[0]); 215a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross exit(EXIT_FAILURE); 216a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross } 217a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 2180349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau infd = open(in, O_RDONLY); 219a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 2200349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau if (infd < 0) 221a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross critical_error_errno("failed to open input image"); 222a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 2230349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau read_ext(infd); 2240349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau 2250349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau build_sparse_ext(infd, in); 226a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 2270349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau close(infd); 228a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 2290349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau if (strcmp(out, "-")) { 2300349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau outfd = open(out, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); 2310349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau if (outfd < 0) { 2320349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau error_errno("open"); 2330349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau return EXIT_FAILURE; 2340349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau } 2350349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau } else { 2360349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau outfd = STDOUT_FILENO; 2370349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau } 238a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 239dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross write_ext4_image(outfd, gzip, sparse, crc); 2400349bd9f14d252673a7a25767da4a80121aaaaf2Anatol Pomazau close(outfd); 241a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross 242a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross return 0; 243a7ed433f2dc0116627a93b18fbb260f0665ca0cbColin Cross} 244