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