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