128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross/*
20c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross * Copyright (C) 2012 The Android Open Source Project
328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *
428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * Licensed under the Apache License, Version 2.0 (the "License");
528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * you may not use this file except in compliance with the License.
628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * You may obtain a copy of the License at
728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *
828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *      http://www.apache.org/licenses/LICENSE-2.0
928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *
1028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * Unless required by applicable law or agreed to in writing, software
1128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * distributed under the License is distributed on an "AS IS" BASIS,
1228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * See the License for the specific language governing permissions and
1428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * limitations under the License.
1528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross */
1628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
170c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define _FILE_OFFSET_BITS 64
180c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define _LARGEFILE64_SOURCE 1
1928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
2028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <fcntl.h>
210c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <stdbool.h>
2228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <stdio.h>
2328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <stdlib.h>
2428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <string.h>
250c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <sys/types.h>
2628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <sys/stat.h>
2728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <sys/types.h>
280c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <unistd.h>
2928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
300c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#include <sparse/sparse.h>
3128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
320c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#ifndef O_BINARY
330c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define O_BINARY 0
340c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#endif
3528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
360c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#if defined(__APPLE__) && defined(__MACH__)
370c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define lseek64 lseek
380c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#define off64_t off_t
390c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross#endif
4028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
410c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Crossvoid usage()
4228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{
430c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross    fprintf(stderr, "Usage: img2simg <raw_image_file> <sparse_image_file> [<block_size>]\n");
4428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross}
4528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
4628fa5bc347390480fe190294c6c385b6a9f0d68bColin Crossint main(int argc, char *argv[])
4728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{
480c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	int in;
490c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	int out;
500c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	int ret;
510c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	struct sparse_file *s;
520c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	unsigned int block_size = 4096;
530c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	off64_t len;
540c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross
550c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (argc < 3 || argc > 4) {
560c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		usage();
570c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
5828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
5928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
600c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (argc == 4) {
610c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		block_size = atoi(argv[3]);
620c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
6328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
640c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (block_size < 1024 || block_size % 4 != 0) {
650c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		usage();
660c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
670c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
6828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
690c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (strcmp(argv[1], "-") == 0) {
700c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		in = STDIN_FILENO;
710c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	} else {
720c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		in = open(argv[1], O_RDONLY | O_BINARY);
730c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		if (in < 0) {
740c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			fprintf(stderr, "Cannot open input file %s\n", argv[1]);
750c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			exit(-1);
760c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		}
770c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
7828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
790c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (strcmp(argv[2], "-") == 0) {
800c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		out = STDOUT_FILENO;
810c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	} else {
820c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664);
830c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		if (out < 0) {
840c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			fprintf(stderr, "Cannot open output file %s\n", argv[2]);
850c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			exit(-1);
860c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		}
8728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
8828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
890c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	len = lseek64(in, 0, SEEK_END);
900c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	lseek64(in, 0, SEEK_SET);
9128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
920c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	s = sparse_file_new(block_size, len);
930c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (!s) {
940c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		fprintf(stderr, "Failed to create sparse file\n");
950c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
960c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
9728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
980c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	sparse_file_verbose(s);
990c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	ret = sparse_file_read(s, in, false, false);
1000c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (ret) {
1010c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		fprintf(stderr, "Failed to read file\n");
1020c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
1030c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
10428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
1050c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	ret = sparse_file_write(s, out, false, true, false);
1060c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (ret) {
1070c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		fprintf(stderr, "Failed to write sparse file\n");
1080c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
1090c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
11028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
1110c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	close(in);
1120c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	close(out);
11328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
1140c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	exit(0);
11528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross}
116