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	unsigned int i;
510c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	int ret;
520c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	struct sparse_file *s;
530c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	unsigned int block_size = 4096;
540c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	off64_t len;
550c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross
560c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (argc < 3 || argc > 4) {
570c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		usage();
580c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
5928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
6028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
610c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (argc == 4) {
620c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		block_size = atoi(argv[3]);
630c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
6428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
650c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (block_size < 1024 || block_size % 4 != 0) {
660c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		usage();
670c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
680c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
6928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
700c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (strcmp(argv[1], "-") == 0) {
710c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		in = STDIN_FILENO;
720c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	} else {
730c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		in = open(argv[1], O_RDONLY | O_BINARY);
740c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		if (in < 0) {
750c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			fprintf(stderr, "Cannot open input file %s\n", argv[1]);
760c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			exit(-1);
770c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		}
780c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
7928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
800c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (strcmp(argv[2], "-") == 0) {
810c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		out = STDOUT_FILENO;
820c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	} else {
830c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664);
840c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		if (out < 0) {
850c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			fprintf(stderr, "Cannot open output file %s\n", argv[2]);
860c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross			exit(-1);
870c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		}
8828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
8928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
900c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	len = lseek64(in, 0, SEEK_END);
910c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	lseek64(in, 0, SEEK_SET);
9228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
930c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	s = sparse_file_new(block_size, len);
940c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (!s) {
950c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		fprintf(stderr, "Failed to create sparse file\n");
960c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
970c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
9828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
990c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	sparse_file_verbose(s);
1000c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	ret = sparse_file_read(s, in, false, false);
1010c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (ret) {
1020c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		fprintf(stderr, "Failed to read file\n");
1030c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
1040c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
10528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
1060c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	ret = sparse_file_write(s, out, false, true, false);
1070c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	if (ret) {
1080c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		fprintf(stderr, "Failed to write sparse file\n");
1090c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross		exit(-1);
1100c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	}
11128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
1120c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	close(in);
1130c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	close(out);
11428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
1150c4c47f88dfc15cada154a1cf9b4db88b49890f0Colin Cross	exit(0);
11628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross}
117