make_ext4fs: Allow custom filesystem configs

Before we used the "fs_config" function from
android_filesystem_config.h, but we want to use make_ext4fs with ASEC
containers which will not always be mounted in the same place.

Bug: 6258335
Change-Id: Icf62e3c46425f01434bf92a9823f8d542b0fa5b1
diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c
index c6fb14a..ccba132 100644
--- a/ext4_utils/make_ext4fs.c
+++ b/ext4_utils/make_ext4fs.c
@@ -33,10 +33,6 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#ifdef ANDROID
-#include <private/android_filesystem_config.h>
-#endif
-
 #ifdef USE_MINGW
 
 #include <winsock2.h>
@@ -102,7 +98,7 @@
 /* Read a local directory and create the same tree in the generated filesystem.
    Calls itself recursively with each directory in the given directory */
 static u32 build_directory_structure(const char *full_path, const char *dir_path,
-		u32 dir_inode, int android)
+		u32 dir_inode, fs_config_func_t fs_config_func)
 {
 	int entries = 0;
 	struct dentry *dentries;
@@ -145,13 +141,13 @@
 		dentries[i].size = stat.st_size;
 		dentries[i].mode = stat.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO);
 		dentries[i].mtime = stat.st_mtime;
-		if (android) {
+		if (fs_config_func != NULL) {
 #ifdef ANDROID
 			unsigned int mode = 0;
 			unsigned int uid = 0;
 			unsigned int gid = 0;
 			int dir = S_ISDIR(stat.st_mode);
-			fs_config(dentries[i].path, dir, &uid, &gid, &mode);
+			fs_config_func(dentries[i].path, dir, &uid, &gid, &mode);
 			dentries[i].mode = mode;
 			dentries[i].uid = uid;
 			dentries[i].gid = gid;
@@ -192,7 +188,7 @@
 			entry_inode = make_file(dentries[i].full_path, dentries[i].size);
 		} else if (dentries[i].file_type == EXT4_FT_DIR) {
 			entry_inode = build_directory_structure(dentries[i].full_path,
-					dentries[i].path, inode, android);
+					dentries[i].path, inode, fs_config_func);
 		} else if (dentries[i].file_type == EXT4_FT_SYMLINK) {
 			entry_inode = make_link(dentries[i].full_path, dentries[i].link);
 		} else {
@@ -297,14 +293,14 @@
 		return EXIT_FAILURE;
 	}
 
-	status = make_ext4fs_internal(fd, NULL, NULL, 0, 0, 0, 0, 1, 0);
+	status = make_ext4fs_internal(fd, NULL, NULL, NULL, 0, 0, 0, 1, 0);
 	close(fd);
 
 	return status;
 }
 
 int make_ext4fs_internal(int fd, const char *directory,
-                         char *mountpoint, int android, int gzip, int sparse,
+                         char *mountpoint, fs_config_func_t fs_config_func, int gzip, int sparse,
                          int crc, int wipe, int init_itabs)
 {
 	u32 root_inode_num;
@@ -397,7 +393,7 @@
 	root_inode_num = build_default_directory_structure();
 #else
 	if (directory)
-		root_inode_num = build_directory_structure(directory, mountpoint, 0, android);
+		root_inode_num = build_directory_structure(directory, mountpoint, 0, fs_config_func);
 	else
 		root_inode_num = build_default_directory_structure();
 #endif
diff --git a/ext4_utils/make_ext4fs.h b/ext4_utils/make_ext4fs.h
index bda9c68..4e2c307 100644
--- a/ext4_utils/make_ext4fs.h
+++ b/ext4_utils/make_ext4fs.h
@@ -24,10 +24,13 @@
 extern "C" {
 #endif
 
+typedef void (*fs_config_func_t)(const char *path, int dir, unsigned *uid, unsigned *gid,
+        unsigned *mode);
+
 void reset_ext4fs_info();
 int make_ext4fs(const char *filename, s64 len);
 int make_ext4fs_internal(int fd, const char *directory,
-                         char *mountpoint, int android, int gzip, int sparse,
+                         char *mountpoint, fs_config_func_t fs_config_func, int gzip, int sparse,
                          int crc, int wipe, int init_itabs);
 
 #ifdef __cplusplus
diff --git a/ext4_utils/make_ext4fs_main.c b/ext4_utils/make_ext4fs_main.c
index d9e1de7..3aab795 100644
--- a/ext4_utils/make_ext4fs_main.c
+++ b/ext4_utils/make_ext4fs_main.c
@@ -24,6 +24,10 @@
 #include <sys/disk.h>
 #endif
 
+#ifdef ANDROID
+#include <private/android_filesystem_config.h>
+#endif
+
 #include "make_ext4fs.h"
 
 #ifndef USE_MINGW /* O_BINARY is windows-specific flag */
@@ -48,7 +52,7 @@
 	const char *filename = NULL;
 	const char *directory = NULL;
 	char *mountpoint = "";
-	int android = 0;
+	fs_config_func_t fs_config_func = NULL;
 	int gzip = 0;
 	int sparse = 0;
 	int crc = 0;
@@ -84,8 +88,14 @@
 			force = 1;
 			break;
 		case 'a':
-			android = 1;
+#ifdef ANDROID
+			fs_config_func = fs_config;
 			mountpoint = optarg;
+#else
+			fprintf(stderr, "can't set android permissions - built without android support\n");
+			usage(argv[0]);
+			exit(EXIT_FAILURE);
+#endif
 			break;
 		case 'w':
 			wipe = 1;
@@ -156,7 +166,7 @@
 		fd = STDOUT_FILENO;
 	}
 
-	exitcode = make_ext4fs_internal(fd, directory, mountpoint, android, gzip,
+	exitcode = make_ext4fs_internal(fd, directory, mountpoint, fs_config_func, gzip,
 			sparse, crc, wipe, init_itabs);
 	close(fd);