1 /* 2 * Copyright (C) 2015 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 <stdbool.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <unistd.h> 21 22 #include <private/android_filesystem_config.h> 23 24 /* 25 * This program expects android_device_dirs and android_device_files 26 * to be defined in the supplied android_filesystem_config.h file in 27 * the device/<vendor>/<product> $(TARGET_DEVICE_DIR). Then generates 28 * the binary format used in the /system/etc/fs_config_dirs and 29 * the /system/etc/fs_config_files to be used by the runtimes. 30 */ 31 #include "android_filesystem_config.h" 32 33 #ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS 34 static const struct fs_path_config android_device_dirs[] = { 35 }; 36 #endif 37 38 #ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES 39 static const struct fs_path_config android_device_files[] = { 40 #ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS 41 { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" }, 42 #endif 43 { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_files" }, 44 }; 45 #endif 46 47 static void usage() { 48 fprintf(stderr, 49 "Generate binary content for fs_config_dirs (-D) and fs_config_files (-F)\n" 50 "from device-specific android_filesystem_config.h override\n\n" 51 "Usage: fs_config_generate -D|-F [-o output-file]\n"); 52 } 53 54 int main(int argc, char** argv) { 55 const struct fs_path_config *pc; 56 const struct fs_path_config *end; 57 bool dir = false, file = false; 58 FILE *fp = stdout; 59 int opt; 60 61 while((opt = getopt(argc, argv, "DFho:")) != -1) { 62 switch(opt) { 63 case 'D': 64 if (file) { 65 fprintf(stderr, "Must specify only -D or -F\n"); 66 usage(); 67 exit(EXIT_FAILURE); 68 } 69 dir = true; 70 break; 71 case 'F': 72 if (dir) { 73 fprintf(stderr, "Must specify only -F or -D\n"); 74 usage(); 75 exit(EXIT_FAILURE); 76 } 77 file = true; 78 break; 79 case 'o': 80 if (fp != stdout) { 81 fprintf(stderr, "Specify only one output file\n"); 82 usage(); 83 exit(EXIT_FAILURE); 84 } 85 fp = fopen(optarg, "wb"); 86 if (fp == NULL) { 87 fprintf(stderr, "Can not open \"%s\"\n", optarg); 88 exit(EXIT_FAILURE); 89 } 90 break; 91 case 'h': 92 usage(); 93 exit(EXIT_SUCCESS); 94 default: 95 usage(); 96 exit(EXIT_FAILURE); 97 } 98 } 99 100 if (!file && !dir) { 101 fprintf(stderr, "Must specify either -F or -D\n"); 102 usage(); 103 exit(EXIT_FAILURE); 104 } 105 106 if (dir) { 107 pc = android_device_dirs; 108 end = &android_device_dirs[sizeof(android_device_dirs) / sizeof(android_device_dirs[0])]; 109 } else { 110 pc = android_device_files; 111 end = &android_device_files[sizeof(android_device_files) / sizeof(android_device_files[0])]; 112 } 113 for(; (pc < end) && pc->prefix; pc++) { 114 char buffer[512]; 115 ssize_t len = fs_config_generate(buffer, sizeof(buffer), pc); 116 if (len < 0) { 117 fprintf(stderr, "Entry too large\n"); 118 exit(EXIT_FAILURE); 119 } 120 if (fwrite(buffer, 1, len, fp) != (size_t)len) { 121 fprintf(stderr, "Write failure\n"); 122 exit(EXIT_FAILURE); 123 } 124 } 125 fclose(fp); 126 127 return 0; 128 } 129