128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross/* 20c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross * Copyright (C) 2012 The Android Open Source Project 328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * 428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * you may not use this file except in compliance with the License. 628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * You may obtain a copy of the License at 728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * 828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * http://www.apache.org/licenses/LICENSE-2.0 928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * 1028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * Unless required by applicable law or agreed to in writing, software 1128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * distributed under the License is distributed on an "AS IS" BASIS, 1228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * See the License for the specific language governing permissions and 1428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * limitations under the License. 1528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross */ 1628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 170c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define _FILE_OFFSET_BITS 64 180c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define _LARGEFILE64_SOURCE 1 1928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 2028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <fcntl.h> 210c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <stdbool.h> 2228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <stdio.h> 2328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <stdlib.h> 2428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <string.h> 250c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <sys/types.h> 2628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <sys/stat.h> 2728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <sys/types.h> 280c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <unistd.h> 2928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 300c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <sparse/sparse.h> 3128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 320c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#ifndef O_BINARY 330c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define O_BINARY 0 340c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#endif 3528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 360c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#if defined(__APPLE__) && defined(__MACH__) 370c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define lseek64 lseek 380c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define off64_t off_t 390c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#endif 4028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 410c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Crossvoid usage() 4228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{ 430c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross fprintf(stderr, "Usage: img2simg <raw_image_file> <sparse_image_file> [<block_size>]\n"); 4428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross} 4528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 4628fa5bc347390480fe190294c6c385b6a9f0d68bColin Crossint main(int argc, char *argv[]) 4728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{ 480c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross int in; 490c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross int out; 500c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross int ret; 510c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross struct sparse_file *s; 520c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross unsigned int block_size = 4096; 530c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross off64_t len; 540c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross 550c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (argc < 3 || argc > 4) { 560c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross usage(); 570c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(-1); 5828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross } 5928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 600c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (argc == 4) { 610c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross block_size = atoi(argv[3]); 620c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 6328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 640c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (block_size < 1024 || block_size % 4 != 0) { 650c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross usage(); 660c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(-1); 670c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 6828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 690c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (strcmp(argv[1], "-") == 0) { 700c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross in = STDIN_FILENO; 710c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } else { 720c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross in = open(argv[1], O_RDONLY | O_BINARY); 730c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (in < 0) { 740c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross fprintf(stderr, "Cannot open input file %s\n", argv[1]); 750c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(-1); 760c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 770c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 7828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 790c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (strcmp(argv[2], "-") == 0) { 800c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross out = STDOUT_FILENO; 810c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } else { 820c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664); 830c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (out < 0) { 840c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross fprintf(stderr, "Cannot open output file %s\n", argv[2]); 850c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(-1); 860c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 8728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross } 8828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 890c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross len = lseek64(in, 0, SEEK_END); 900c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross lseek64(in, 0, SEEK_SET); 9128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 920c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross s = sparse_file_new(block_size, len); 930c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (!s) { 940c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross fprintf(stderr, "Failed to create sparse file\n"); 950c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(-1); 960c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 9728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 980c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross sparse_file_verbose(s); 990c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross ret = sparse_file_read(s, in, false, false); 1000c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (ret) { 1010c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross fprintf(stderr, "Failed to read file\n"); 1020c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(-1); 1030c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 10428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 1050c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross ret = sparse_file_write(s, out, false, true, false); 1060c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross if (ret) { 1070c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross fprintf(stderr, "Failed to write sparse file\n"); 1080c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(-1); 1090c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross } 11028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 1110c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross close(in); 1120c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross close(out); 11328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross 1140c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross exit(0); 11528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross} 116