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#define _GNU_SOURCE 20a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 21a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <fcntl.h> 22a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <stdbool.h> 23a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <stdio.h> 24a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <stdlib.h> 25a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <string.h> 26a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sys/types.h> 27a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sys/stat.h> 28a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sys/types.h> 29a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <unistd.h> 30a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 31a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#include <sparse/sparse.h> 32a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 33a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#ifndef O_BINARY 34a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#define O_BINARY 0 35a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner#endif 36a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 37a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turnervoid usage() 38a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner{ 39a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Usage: simg2simg <sparse image file> <sparse_image_file> <max_size>\n"); 40a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner} 41a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 42a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turnerint main(int argc, char *argv[]) 43a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner{ 44a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int in; 45a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int out; 46a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int i; 47a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int ret; 48a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner struct sparse_file *s; 49a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int64_t max_size; 50a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner struct sparse_file **out_s; 51a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner int files; 52a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner char filename[4096]; 53a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 54a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (argc != 4) { 55a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner usage(); 56a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 57a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 58a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 59a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner max_size = atoll(argv[3]); 60a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 61a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner in = open(argv[1], O_RDONLY | O_BINARY); 62a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (in < 0) { 63a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Cannot open input file %s\n", argv[1]); 64a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 65a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 66a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 67a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner s = sparse_file_import(in, true, false); 68a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (!s) { 69a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to import sparse file\n"); 70a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 71a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 72a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 73a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner files = sparse_file_resparse(s, max_size, NULL, 0); 74a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (files < 0) { 75a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to resparse\n"); 76a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 77a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 78a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 79a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner out_s = calloc(sizeof(struct sparse_file *), files); 80a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (!out_s) { 81a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to allocate sparse file array\n"); 82a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 83a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 84a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 85a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner files = sparse_file_resparse(s, max_size, out_s, files); 86a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (files < 0) { 87a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to resparse\n"); 88a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 89a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 90a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 91a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner for (i = 0; i < files; i++) { 92a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner ret = snprintf(filename, sizeof(filename), "%s.%d", argv[2], i); 93a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (ret >= (int)sizeof(filename)) { 94a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Filename too long\n"); 95a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 96a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 97a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 98a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner out = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664); 99a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (out < 0) { 100a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Cannot open output file %s\n", argv[2]); 101a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 102a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 103a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 104a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner ret = sparse_file_write(out_s[i], out, false, true, false); 105a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner if (ret) { 106a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner fprintf(stderr, "Failed to write sparse file\n"); 107a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(-1); 108a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 109a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner close(out); 110a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner } 111a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 112a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner close(in); 113a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner 114a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner exit(0); 115a2394cf2fab37ca4ec91e57db74f06f15a3656beDavid 'Digit' Turner} 116