libsparse: add function to resparse a file and a utility to use it

Add sparse_file_repsarse, which splits chunks in an existing sparse
file such that the maximum size of a chunk, plus a header and footer,
is smaller than the given size.  This will allow multiple smaller
sparse files to result in the same data as a large sparse file.

Change-Id: I177abdb958a23d5afd394ff265c5b0c6a3ff22fa
diff --git a/libsparse/simg2img.c b/libsparse/simg2img.c
index ab35583..95e9b5b 100644
--- a/libsparse/simg2img.c
+++ b/libsparse/simg2img.c
@@ -26,50 +26,62 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
 void usage()
 {
-  fprintf(stderr, "Usage: simg2img <sparse_image_file> <raw_image_file>\n");
+  fprintf(stderr, "Usage: simg2img <sparse_image_files> <raw_image_file>\n");
 }
 
 int main(int argc, char *argv[])
 {
 	int in;
 	int out;
-	unsigned int i;
+	int i;
 	int ret;
 	struct sparse_file *s;
 
-	if (argc != 3) {
+	if (argc < 3) {
 		usage();
 		exit(-1);
 	}
 
-	if (strcmp(argv[1], "-") == 0) {
-		in = STDIN_FILENO;
-	} else {
-		if ((in = open(argv[1], O_RDONLY)) == 0) {
-			fprintf(stderr, "Cannot open input file %s\n", argv[1]);
-			exit(-1);
-		}
-	}
-
-	if (strcmp(argv[2], "-") == 0) {
-		out = STDOUT_FILENO;
-	} else {
-		if ((out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666)) == 0) {
-			fprintf(stderr, "Cannot open output file %s\n", argv[2]);
-			exit(-1);
-		}
-	}
-
-	s = sparse_file_import(in, true, false);
-	if (!s) {
-		fprintf(stderr, "Failed to read sparse file\n");
+	out = open(argv[argc - 1], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664);
+	if (out < 0) {
+		fprintf(stderr, "Cannot open output file %s\n", argv[argc - 1]);
 		exit(-1);
 	}
-	ret = sparse_file_write(s, out, false, false, false);
 
-	close(in);
+	for (i = 1; i < argc - 1; i++) {
+		if (strcmp(argv[i], "-") == 0) {
+			in = STDIN_FILENO;
+		} else {
+			in = open(argv[i], O_RDONLY | O_BINARY);
+			if (in < 0) {
+				fprintf(stderr, "Cannot open input file %s\n", argv[i]);
+				exit(-1);
+			}
+		}
+
+		s = sparse_file_import(in, true, false);
+		if (!s) {
+			fprintf(stderr, "Failed to read sparse file\n");
+			exit(-1);
+		}
+
+		lseek(out, SEEK_SET, 0);
+
+		ret = sparse_file_write(s, out, false, false, false);
+		if (ret < 0) {
+			fprintf(stderr, "Cannot write output file\n");
+			exit(-1);
+		}
+		sparse_file_destroy(s);
+		close(in);
+	}
+
 	close(out);
 
 	exit(0);