xref: /aosp_15_r20/system/core/libsparse/img2simg.cpp (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1*00c7fec1SAndroid Build Coastguard Worker /*
2*00c7fec1SAndroid Build Coastguard Worker  * Copyright (C) 2012 The Android Open Source Project
3*00c7fec1SAndroid Build Coastguard Worker  *
4*00c7fec1SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*00c7fec1SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*00c7fec1SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*00c7fec1SAndroid Build Coastguard Worker  *
8*00c7fec1SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*00c7fec1SAndroid Build Coastguard Worker  *
10*00c7fec1SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*00c7fec1SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*00c7fec1SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*00c7fec1SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*00c7fec1SAndroid Build Coastguard Worker  * limitations under the License.
15*00c7fec1SAndroid Build Coastguard Worker  */
16*00c7fec1SAndroid Build Coastguard Worker 
17*00c7fec1SAndroid Build Coastguard Worker #define _FILE_OFFSET_BITS 64
18*00c7fec1SAndroid Build Coastguard Worker #define _LARGEFILE64_SOURCE 1
19*00c7fec1SAndroid Build Coastguard Worker 
20*00c7fec1SAndroid Build Coastguard Worker #include <fcntl.h>
21*00c7fec1SAndroid Build Coastguard Worker #include <stdbool.h>
22*00c7fec1SAndroid Build Coastguard Worker #include <stdio.h>
23*00c7fec1SAndroid Build Coastguard Worker #include <stdlib.h>
24*00c7fec1SAndroid Build Coastguard Worker #include <string.h>
25*00c7fec1SAndroid Build Coastguard Worker #include <sys/stat.h>
26*00c7fec1SAndroid Build Coastguard Worker #include <sys/types.h>
27*00c7fec1SAndroid Build Coastguard Worker #include <unistd.h>
28*00c7fec1SAndroid Build Coastguard Worker 
29*00c7fec1SAndroid Build Coastguard Worker #include <sparse/sparse.h>
30*00c7fec1SAndroid Build Coastguard Worker 
31*00c7fec1SAndroid Build Coastguard Worker #ifndef O_BINARY
32*00c7fec1SAndroid Build Coastguard Worker #define O_BINARY 0
33*00c7fec1SAndroid Build Coastguard Worker #endif
34*00c7fec1SAndroid Build Coastguard Worker 
35*00c7fec1SAndroid Build Coastguard Worker #if defined(__APPLE__) && defined(__MACH__)
36*00c7fec1SAndroid Build Coastguard Worker #define lseek64 lseek
37*00c7fec1SAndroid Build Coastguard Worker #define off64_t off_t
38*00c7fec1SAndroid Build Coastguard Worker #endif
39*00c7fec1SAndroid Build Coastguard Worker 
usage()40*00c7fec1SAndroid Build Coastguard Worker void usage() {
41*00c7fec1SAndroid Build Coastguard Worker   fprintf(stderr, "Usage: img2simg [-s] <raw_image_file> <sparse_image_file> [<block_size>]\n");
42*00c7fec1SAndroid Build Coastguard Worker }
43*00c7fec1SAndroid Build Coastguard Worker 
main(int argc,char * argv[])44*00c7fec1SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
45*00c7fec1SAndroid Build Coastguard Worker   char *arg_in;
46*00c7fec1SAndroid Build Coastguard Worker   char *arg_out;
47*00c7fec1SAndroid Build Coastguard Worker   enum sparse_read_mode mode = SPARSE_READ_MODE_NORMAL;
48*00c7fec1SAndroid Build Coastguard Worker   int extra;
49*00c7fec1SAndroid Build Coastguard Worker   int in;
50*00c7fec1SAndroid Build Coastguard Worker   int opt;
51*00c7fec1SAndroid Build Coastguard Worker   int out;
52*00c7fec1SAndroid Build Coastguard Worker   int ret;
53*00c7fec1SAndroid Build Coastguard Worker   struct sparse_file* s;
54*00c7fec1SAndroid Build Coastguard Worker   unsigned int block_size = 4096;
55*00c7fec1SAndroid Build Coastguard Worker   off64_t len;
56*00c7fec1SAndroid Build Coastguard Worker 
57*00c7fec1SAndroid Build Coastguard Worker   while ((opt = getopt(argc, argv, "s")) != -1) {
58*00c7fec1SAndroid Build Coastguard Worker     switch (opt) {
59*00c7fec1SAndroid Build Coastguard Worker       case 's':
60*00c7fec1SAndroid Build Coastguard Worker         mode = SPARSE_READ_MODE_HOLE;
61*00c7fec1SAndroid Build Coastguard Worker         break;
62*00c7fec1SAndroid Build Coastguard Worker       default:
63*00c7fec1SAndroid Build Coastguard Worker         usage();
64*00c7fec1SAndroid Build Coastguard Worker         exit(EXIT_FAILURE);
65*00c7fec1SAndroid Build Coastguard Worker     }
66*00c7fec1SAndroid Build Coastguard Worker   }
67*00c7fec1SAndroid Build Coastguard Worker 
68*00c7fec1SAndroid Build Coastguard Worker   extra = argc - optind;
69*00c7fec1SAndroid Build Coastguard Worker   if (extra < 2 || extra > 3) {
70*00c7fec1SAndroid Build Coastguard Worker     usage();
71*00c7fec1SAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
72*00c7fec1SAndroid Build Coastguard Worker   }
73*00c7fec1SAndroid Build Coastguard Worker 
74*00c7fec1SAndroid Build Coastguard Worker   if (extra == 3) {
75*00c7fec1SAndroid Build Coastguard Worker     block_size = atoi(argv[optind + 2]);
76*00c7fec1SAndroid Build Coastguard Worker   }
77*00c7fec1SAndroid Build Coastguard Worker 
78*00c7fec1SAndroid Build Coastguard Worker   if (block_size < 1024 || block_size % 4 != 0) {
79*00c7fec1SAndroid Build Coastguard Worker     usage();
80*00c7fec1SAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
81*00c7fec1SAndroid Build Coastguard Worker   }
82*00c7fec1SAndroid Build Coastguard Worker 
83*00c7fec1SAndroid Build Coastguard Worker   arg_in = argv[optind];
84*00c7fec1SAndroid Build Coastguard Worker   if (strcmp(arg_in, "-") == 0) {
85*00c7fec1SAndroid Build Coastguard Worker     in = STDIN_FILENO;
86*00c7fec1SAndroid Build Coastguard Worker   } else {
87*00c7fec1SAndroid Build Coastguard Worker     in = open(arg_in, O_RDONLY | O_BINARY);
88*00c7fec1SAndroid Build Coastguard Worker     if (in < 0) {
89*00c7fec1SAndroid Build Coastguard Worker       fprintf(stderr, "Cannot open input file %s\n", arg_in);
90*00c7fec1SAndroid Build Coastguard Worker       exit(EXIT_FAILURE);
91*00c7fec1SAndroid Build Coastguard Worker     }
92*00c7fec1SAndroid Build Coastguard Worker   }
93*00c7fec1SAndroid Build Coastguard Worker 
94*00c7fec1SAndroid Build Coastguard Worker   arg_out = argv[optind + 1];
95*00c7fec1SAndroid Build Coastguard Worker   if (strcmp(arg_out, "-") == 0) {
96*00c7fec1SAndroid Build Coastguard Worker     out = STDOUT_FILENO;
97*00c7fec1SAndroid Build Coastguard Worker   } else {
98*00c7fec1SAndroid Build Coastguard Worker     out = open(arg_out, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664);
99*00c7fec1SAndroid Build Coastguard Worker     if (out < 0) {
100*00c7fec1SAndroid Build Coastguard Worker       fprintf(stderr, "Cannot open output file %s\n", arg_out);
101*00c7fec1SAndroid Build Coastguard Worker       exit(EXIT_FAILURE);
102*00c7fec1SAndroid Build Coastguard Worker     }
103*00c7fec1SAndroid Build Coastguard Worker   }
104*00c7fec1SAndroid Build Coastguard Worker 
105*00c7fec1SAndroid Build Coastguard Worker   len = lseek64(in, 0, SEEK_END);
106*00c7fec1SAndroid Build Coastguard Worker   lseek64(in, 0, SEEK_SET);
107*00c7fec1SAndroid Build Coastguard Worker 
108*00c7fec1SAndroid Build Coastguard Worker   s = sparse_file_new(block_size, len);
109*00c7fec1SAndroid Build Coastguard Worker   if (!s) {
110*00c7fec1SAndroid Build Coastguard Worker     fprintf(stderr, "Failed to create sparse file\n");
111*00c7fec1SAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
112*00c7fec1SAndroid Build Coastguard Worker   }
113*00c7fec1SAndroid Build Coastguard Worker 
114*00c7fec1SAndroid Build Coastguard Worker   sparse_file_verbose(s);
115*00c7fec1SAndroid Build Coastguard Worker   ret = sparse_file_read(s, in, mode, false);
116*00c7fec1SAndroid Build Coastguard Worker   if (ret) {
117*00c7fec1SAndroid Build Coastguard Worker     fprintf(stderr, "Failed to read file\n");
118*00c7fec1SAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
119*00c7fec1SAndroid Build Coastguard Worker   }
120*00c7fec1SAndroid Build Coastguard Worker 
121*00c7fec1SAndroid Build Coastguard Worker   ret = sparse_file_write(s, out, false, true, false);
122*00c7fec1SAndroid Build Coastguard Worker   if (ret) {
123*00c7fec1SAndroid Build Coastguard Worker     fprintf(stderr, "Failed to write sparse file\n");
124*00c7fec1SAndroid Build Coastguard Worker     exit(EXIT_FAILURE);
125*00c7fec1SAndroid Build Coastguard Worker   }
126*00c7fec1SAndroid Build Coastguard Worker 
127*00c7fec1SAndroid Build Coastguard Worker   close(in);
128*00c7fec1SAndroid Build Coastguard Worker   close(out);
129*00c7fec1SAndroid Build Coastguard Worker 
130*00c7fec1SAndroid Build Coastguard Worker   exit(EXIT_SUCCESS);
131*00c7fec1SAndroid Build Coastguard Worker }
132