1a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner/* 2a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * Copyright (C) 2012 The Android Open Source Project 3a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * 4a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * Licensed under the Apache License, Version 2.0 (the "License"); 5a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * you may not use this file except in compliance with the License. 6a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * You may obtain a copy of the License at 7a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * 8a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * http://www.apache.org/licenses/LICENSE-2.0 9a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * 10a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * Unless required by applicable law or agreed to in writing, software 11a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * distributed under the License is distributed on an "AS IS" BASIS, 12a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * See the License for the specific language governing permissions and 14a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner * limitations under the License. 15a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner */ 16a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 17a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#define _FILE_OFFSET_BITS 64 18a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#define _LARGEFILE64_SOURCE 1 19a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 20a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <fcntl.h> 21a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <stdbool.h> 22a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <stdio.h> 23a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <stdlib.h> 24a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <string.h> 25a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sys/types.h> 26a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sys/stat.h> 27a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sys/types.h> 28a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <unistd.h> 29a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 30a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sparse/sparse.h> 31a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 32a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#ifndef O_BINARY 33a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#define O_BINARY 0 34a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#endif 35a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 36a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#if defined(__APPLE__) && defined(__MACH__) 37a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#define lseek64 lseek 38a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#define off64_t off_t 39a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#endif 40a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 41a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turnervoid usage() 42a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner{ 43a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Usage: img2simg <raw_image_file> <sparse_image_file> [<block_size>]\n"); 44a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner} 45a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 46a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turnerint main(int argc, char *argv[]) 47a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner{ 48a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int in; 49a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int out; 50a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int ret; 51a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner struct sparse_file *s; 52a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner unsigned int block_size = 4096; 53a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner off64_t len; 54a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 55a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (argc < 3 || argc > 4) { 56a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner usage(); 57a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 58a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 59a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 60a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (argc == 4) { 61a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner block_size = atoi(argv[3]); 62a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 63a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 64a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (block_size < 1024 || block_size % 4 != 0) { 65a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner usage(); 66a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 67a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 68a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 69a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (strcmp(argv[1], "-") == 0) { 70a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner in = STDIN_FILENO; 71a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } else { 72a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner in = open(argv[1], O_RDONLY | O_BINARY); 73a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (in < 0) { 74a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Cannot open input file %s\n", argv[1]); 75a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 76a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 77a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 78a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 79a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (strcmp(argv[2], "-") == 0) { 80a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner out = STDOUT_FILENO; 81a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } else { 82a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664); 83a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (out < 0) { 84a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Cannot open output file %s\n", argv[2]); 85a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 86a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 87a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 88a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 89a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner len = lseek64(in, 0, SEEK_END); 90a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner lseek64(in, 0, SEEK_SET); 91a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 92a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner s = sparse_file_new(block_size, len); 93a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (!s) { 94a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to create sparse file\n"); 95a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 96a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 97a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 98a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner sparse_file_verbose(s); 99a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner ret = sparse_file_read(s, in, false, false); 100a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (ret) { 101a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to read file\n"); 102a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 103a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 104a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 105a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner ret = sparse_file_write(s, out, false, true, false); 106a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (ret) { 107a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to write sparse file\n"); 108a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 109a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 110a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 111a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner close(in); 112a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner close(out); 113a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 114a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(0); 115a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner} 116