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