• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <fcntl.h>
18 #include <libgen.h>
19 #include <unistd.h>
20 
21 #if defined(__linux__)
22 #include <linux/fs.h>
23 #elif defined(__APPLE__) && defined(__MACH__)
24 #include <sys/disk.h>
25 #endif
26 
27 #ifdef ANDROID
28 #include <private/android_filesystem_config.h>
29 #endif
30 
31 #include "make_ext4fs.h"
32 
33 #ifndef USE_MINGW /* O_BINARY is windows-specific flag */
34 #define O_BINARY 0
35 #endif
36 
37 extern struct fs_info info;
38 
39 
usage(char * path)40 static void usage(char *path)
41 {
42 	fprintf(stderr, "%s [ -l <len> ] [ -j <journal size> ] [ -b <block_size> ]\n", basename(path));
43 	fprintf(stderr, "    [ -g <blocks per group> ] [ -i <inodes> ] [ -I <inode size> ]\n");
44 	fprintf(stderr, "    [ -L <label> ] [ -f ] [ -a <android mountpoint> ]\n");
45 	fprintf(stderr, "    [ -S file_contexts ]\n");
46 	fprintf(stderr, "    [ -z | -s ] [ -t ] [ -w ] [ -c ] [ -J ]\n");
47 	fprintf(stderr, "    <filename> [<directory>]\n");
48 }
49 
main(int argc,char ** argv)50 int main(int argc, char **argv)
51 {
52 	int opt;
53 	const char *filename = NULL;
54 	const char *directory = NULL;
55 	char *mountpoint = "";
56 	fs_config_func_t fs_config_func = NULL;
57 	int gzip = 0;
58 	int sparse = 0;
59 	int crc = 0;
60 	int wipe = 0;
61 	int init_itabs = 0;
62 	int fd;
63 	int exitcode;
64 	struct selabel_handle *sehnd = NULL;
65 #ifdef HAVE_SELINUX
66 	struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "" } };
67 #endif
68 
69 	while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:fwzJsctS:")) != -1) {
70 		switch (opt) {
71 		case 'l':
72 			info.len = parse_num(optarg);
73 			break;
74 		case 'j':
75 			info.journal_blocks = parse_num(optarg);
76 			break;
77 		case 'b':
78 			info.block_size = parse_num(optarg);
79 			break;
80 		case 'g':
81 			info.blocks_per_group = parse_num(optarg);
82 			break;
83 		case 'i':
84 			info.inodes = parse_num(optarg);
85 			break;
86 		case 'I':
87 			info.inode_size = parse_num(optarg);
88 			break;
89 		case 'L':
90 			info.label = optarg;
91 			break;
92 		case 'f':
93 			force = 1;
94 			break;
95 		case 'a':
96 #ifdef ANDROID
97 			fs_config_func = fs_config;
98 			mountpoint = optarg;
99 #else
100 			fprintf(stderr, "can't set android permissions - built without android support\n");
101 			usage(argv[0]);
102 			exit(EXIT_FAILURE);
103 #endif
104 			break;
105 		case 'w':
106 			wipe = 1;
107 			break;
108 		case 'z':
109 			gzip = 1;
110 			break;
111 		case 'J':
112 			info.no_journal = 1;
113 			break;
114 		case 'c':
115 			crc = 1;
116 			break;
117 		case 's':
118 			sparse = 1;
119 			break;
120 		case 't':
121 			init_itabs = 1;
122 			break;
123 		case 'S':
124 #ifdef HAVE_SELINUX
125 			seopts[0].value = optarg;
126 			sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
127 			if (!sehnd) {
128 				perror(optarg);
129 				exit(EXIT_FAILURE);
130 			}
131 #endif
132 			   break;
133 		default: /* '?' */
134 			usage(argv[0]);
135 			exit(EXIT_FAILURE);
136 		}
137 	}
138 
139 	if (wipe && sparse) {
140 		fprintf(stderr, "Cannot specifiy both wipe and sparse\n");
141 		usage(argv[0]);
142 		exit(EXIT_FAILURE);
143 	}
144 
145 	if (wipe && gzip) {
146 		fprintf(stderr, "Cannot specifiy both wipe and gzip\n");
147 		usage(argv[0]);
148 		exit(EXIT_FAILURE);
149 	}
150 
151 	if (optind >= argc) {
152 		fprintf(stderr, "Expected filename after options\n");
153 		usage(argv[0]);
154 		exit(EXIT_FAILURE);
155 	}
156 
157 	filename = argv[optind++];
158 
159 	if (optind < argc)
160 		directory = argv[optind++];
161 
162 	if (optind < argc) {
163 		fprintf(stderr, "Unexpected argument: %s\n", argv[optind]);
164 		usage(argv[0]);
165 		exit(EXIT_FAILURE);
166 	}
167 
168 	if (strcmp(filename, "-")) {
169 		fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
170 		if (fd < 0) {
171 			error_errno("open");
172 			return EXIT_FAILURE;
173 		}
174 	} else {
175 		fd = STDOUT_FILENO;
176 	}
177 
178 	exitcode = make_ext4fs_internal(fd, directory, mountpoint, fs_config_func, gzip,
179 			sparse, crc, wipe, init_itabs, sehnd);
180 	close(fd);
181 
182 	return exitcode;
183 }
184