append2simg.c revision de807f2ed8af63a75174933c13705a7529a82914
1de807f2ed8af63a75174933c13705a7529a82914Geremy Condra/* 2de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * Copyright (C) 2013 The Android Open Source Project 3de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * 4de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * Licensed under the Apache License, Version 2.0 (the "License"); 5de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * you may not use this file except in compliance with the License. 6de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * You may obtain a copy of the License at 7de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * 8de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * http://www.apache.org/licenses/LICENSE-2.0 9de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * 10de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * Unless required by applicable law or agreed to in writing, software 11de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * distributed under the License is distributed on an "AS IS" BASIS, 12de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * See the License for the specific language governing permissions and 14de807f2ed8af63a75174933c13705a7529a82914Geremy Condra * limitations under the License. 15de807f2ed8af63a75174933c13705a7529a82914Geremy Condra */ 16de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 17de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#define _FILE_OFFSET_BITS 64 18de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#define _LARGEFILE64_SOURCE 1 19de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 20de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include <errno.h> 21de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include <fcntl.h> 22de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include <stdio.h> 23de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include <stdlib.h> 24de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include <string.h> 25de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include <unistd.h> 26de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 27de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include <sparse/sparse.h> 28de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include "sparse_file.h" 29de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#include "backed_block.h" 30de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 31de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#ifndef O_BINARY 32de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#define O_BINARY 0 33de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#endif 34de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 35de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#if defined(__APPLE__) && defined(__MACH__) 36de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#define lseek64 lseek 37de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#endif 38de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#if defined(__APPLE__) && defined(__MACH__) 39de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#define lseek64 lseek 40de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#define off64_t off_t 41de807f2ed8af63a75174933c13705a7529a82914Geremy Condra#endif 42de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 43de807f2ed8af63a75174933c13705a7529a82914Geremy Condravoid usage() 44de807f2ed8af63a75174933c13705a7529a82914Geremy Condra{ 45de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Usage: append2simg <output> <input>\n"); 46de807f2ed8af63a75174933c13705a7529a82914Geremy Condra} 47de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 48de807f2ed8af63a75174933c13705a7529a82914Geremy Condraint main(int argc, char *argv[]) 49de807f2ed8af63a75174933c13705a7529a82914Geremy Condra{ 50de807f2ed8af63a75174933c13705a7529a82914Geremy Condra int output; 51de807f2ed8af63a75174933c13705a7529a82914Geremy Condra int output_block; 52de807f2ed8af63a75174933c13705a7529a82914Geremy Condra char *output_path; 53de807f2ed8af63a75174933c13705a7529a82914Geremy Condra struct sparse_file *sparse_output; 54de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 55de807f2ed8af63a75174933c13705a7529a82914Geremy Condra int input; 56de807f2ed8af63a75174933c13705a7529a82914Geremy Condra char *input_path; 57de807f2ed8af63a75174933c13705a7529a82914Geremy Condra off64_t input_len; 58de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 59de807f2ed8af63a75174933c13705a7529a82914Geremy Condra if (argc == 3) { 60de807f2ed8af63a75174933c13705a7529a82914Geremy Condra output_path = argv[1]; 61de807f2ed8af63a75174933c13705a7529a82914Geremy Condra input_path = argv[2]; 62de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } else { 63de807f2ed8af63a75174933c13705a7529a82914Geremy Condra usage(); 64de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 65de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } 66de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 67de807f2ed8af63a75174933c13705a7529a82914Geremy Condra output = open(output_path, O_RDWR | O_BINARY); 68de807f2ed8af63a75174933c13705a7529a82914Geremy Condra if (output < 0) { 69de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Couldn't open output file (%s)\n", strerror(errno)); 70de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 71de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } 72de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 73de807f2ed8af63a75174933c13705a7529a82914Geremy Condra sparse_output = sparse_file_import_auto(output, true); 74de807f2ed8af63a75174933c13705a7529a82914Geremy Condra if (!sparse_output) { 75de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Couldn't import output file\n"); 76de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 77de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } 78de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 79de807f2ed8af63a75174933c13705a7529a82914Geremy Condra input = open(input_path, O_RDONLY | O_BINARY); 80de807f2ed8af63a75174933c13705a7529a82914Geremy Condra if (input < 0) { 81de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Couldn't open input file (%s)\n", strerror(errno)); 82de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 83de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } 84de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 85de807f2ed8af63a75174933c13705a7529a82914Geremy Condra input_len = lseek64(input, 0, SEEK_END); 86de807f2ed8af63a75174933c13705a7529a82914Geremy Condra if (input_len < 0) { 87de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Couldn't get input file length (%s)\n", strerror(errno)); 88de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 89de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } else if (input_len % sparse_output->block_size) { 90de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Input file is not a multiple of the output file's block size"); 91de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 92de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } 93de807f2ed8af63a75174933c13705a7529a82914Geremy Condra lseek64(input, 0, SEEK_SET); 94de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 95de807f2ed8af63a75174933c13705a7529a82914Geremy Condra output_block = sparse_output->len / sparse_output->block_size; 96de807f2ed8af63a75174933c13705a7529a82914Geremy Condra if (sparse_file_add_fd(sparse_output, input, 0, input_len, output_block) < 0) { 97de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Couldn't add input file\n"); 98de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 99de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } 100de807f2ed8af63a75174933c13705a7529a82914Geremy Condra sparse_output->len += input_len; 101de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 102de807f2ed8af63a75174933c13705a7529a82914Geremy Condra lseek64(output, 0, SEEK_SET); 103de807f2ed8af63a75174933c13705a7529a82914Geremy Condra if (sparse_file_write(sparse_output, output, false, true, false) < 0) { 104de807f2ed8af63a75174933c13705a7529a82914Geremy Condra fprintf(stderr, "Failed to write sparse file\n"); 105de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(-1); 106de807f2ed8af63a75174933c13705a7529a82914Geremy Condra } 107de807f2ed8af63a75174933c13705a7529a82914Geremy Condra 108de807f2ed8af63a75174933c13705a7529a82914Geremy Condra sparse_file_destroy(sparse_output); 109de807f2ed8af63a75174933c13705a7529a82914Geremy Condra close(output); 110de807f2ed8af63a75174933c13705a7529a82914Geremy Condra close(input); 111de807f2ed8af63a75174933c13705a7529a82914Geremy Condra exit(0); 112de807f2ed8af63a75174933c13705a7529a82914Geremy Condra} 113