Home | History | Annotate | Download | only in fs_config
      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