fs_config_generate.c revision 6024069f378dd95667c078d8360ed515116dd309
106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn/*
206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * Copyright (C) 2015 The Android Open Source Project
306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn *
406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License");
506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * you may not use this file except in compliance with the License.
606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * You may obtain a copy of the License at
706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn *
806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn *      http://www.apache.org/licenses/LICENSE-2.0
906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn *
1006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * Unless required by applicable law or agreed to in writing, software
1106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS,
1206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * See the License for the specific language governing permissions and
1406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * limitations under the License.
1506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn */
1606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
1706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <stdbool.h>
1806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <stdio.h>
1906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <stdlib.h>
2006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <unistd.h>
2106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
2206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <private/android_filesystem_config.h>
2306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
2406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn/*
2506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * This program expects android_device_dirs and android_device_files
2606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * to be defined in the supplied android_filesystem_config.h file in
2706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * the device/<vendor>/<product> $(TARGET_DEVICE_DIR). Then generates
2806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * the binary format used in the /system/etc/fs_config_dirs and
2906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * the /system/etc/fs_config_files to be used by the runtimes.
3006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn */
3106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include "android_filesystem_config.h"
3206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
3306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
3406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  static const struct fs_path_config android_device_dirs[] = {
3506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn};
3606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#endif
3706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
3806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
3906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzynstatic const struct fs_path_config android_device_files[] = {
4006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
4106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
4206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#endif
4306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_files" },
4406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn};
4506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#endif
4606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
4706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzynstatic void usage() {
4806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  fprintf(stderr,
4906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    "Generate binary content for fs_config_dirs (-D) and fs_config_files (-F)\n"
5006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    "from device-specific android_filesystem_config.h override\n\n"
5106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    "Usage: fs_config_generate -D|-F [-o output-file]\n");
5206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn}
5306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
5406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzynint main(int argc, char** argv) {
5506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  const struct fs_path_config *pc;
5606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  const struct fs_path_config *end;
5706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  bool dir = false, file = false;
5806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  FILE *fp = stdout;
5906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  int opt;
6006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
6106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  while((opt = getopt(argc, argv, "DFho:")) != -1) {
6206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    switch(opt) {
6306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'D':
6406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (file) {
6506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Must specify only -D or -F\n");
6606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        usage();
6706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
6806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
6906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      dir = true;
7006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      break;
7106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'F':
7206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (dir) {
7306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Must specify only -F or -D\n");
7406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        usage();
7506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
7606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
7706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      file = true;
7806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      break;
7906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'o':
8006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (fp != stdout) {
8106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Specify only one output file\n");
8206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        usage();
8306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
8406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
856024069f378dd95667c078d8360ed515116dd309Mark Salyzyn      fp = fopen(optarg, "wb");
8606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (fp == NULL) {
8706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Can not open \"%s\"\n", optarg);
8806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
8906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
9006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      break;
9106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'h':
9206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      usage();
9306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_SUCCESS);
9406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    default:
9506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      usage();
9606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_FAILURE);
9706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    }
9806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
9906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
10006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  if (!file && !dir) {
10106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    fprintf(stderr, "Must specify either -F or -D\n");
10206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    usage();
10306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    exit(EXIT_FAILURE);
10406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
10506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
10606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  if (dir) {
10706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    pc = android_device_dirs;
10806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    end = &android_device_dirs[sizeof(android_device_dirs) / sizeof(android_device_dirs[0])];
10906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  } else {
11006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    pc = android_device_files;
11106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    end = &android_device_files[sizeof(android_device_files) / sizeof(android_device_files[0])];
11206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
11306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  for(; (pc < end) && pc->prefix; pc++) {
11406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    char buffer[512];
11506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    ssize_t len = fs_config_generate(buffer, sizeof(buffer), pc);
11606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    if (len < 0) {
11706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      fprintf(stderr, "Entry too large\n");
11806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_FAILURE);
11906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    }
12006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    if (fwrite(buffer, 1, len, fp) != (size_t)len) {
12106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      fprintf(stderr, "Write failure\n");
12206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_FAILURE);
12306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    }
12406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
12506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  fclose(fp);
12606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
12706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  return 0;
12806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn}
129