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
17256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn#include <ctype.h>
1806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <stdbool.h>
1906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <stdio.h>
2006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <stdlib.h>
21256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn#include <string.h>
2206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <unistd.h>
2306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
2406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include <private/android_filesystem_config.h>
2506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
2606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn/*
2706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * This program expects android_device_dirs and android_device_files
2806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * to be defined in the supplied android_filesystem_config.h file in
2906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * the device/<vendor>/<product> $(TARGET_DEVICE_DIR). Then generates
3006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * the binary format used in the /system/etc/fs_config_dirs and
3106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn * the /system/etc/fs_config_files to be used by the runtimes.
3206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn */
335649b31a177f98e0f6601ec03c0e0b4fc0ae07e0Mark Salyzyn#ifdef ANDROID_FILESYSTEM_CONFIG
345649b31a177f98e0f6601ec03c0e0b4fc0ae07e0Mark Salyzyn#include ANDROID_FILESYSTEM_CONFIG
355649b31a177f98e0f6601ec03c0e0b4fc0ae07e0Mark Salyzyn#else
3606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#include "android_filesystem_config.h"
375649b31a177f98e0f6601ec03c0e0b4fc0ae07e0Mark Salyzyn#endif
3806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
3906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
40256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzynstatic const struct fs_path_config android_device_dirs[] = { };
4106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#endif
4206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
4306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
4406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzynstatic const struct fs_path_config android_device_files[] = {
4506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
46256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs"},
47256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "vendor/etc/fs_config_dirs"},
48256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "oem/etc/fs_config_dirs"},
49256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "odm/etc/fs_config_dirs"},
5006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#endif
51256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_files"},
52256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "vendor/etc/fs_config_files"},
53256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "oem/etc/fs_config_files"},
54256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    {0000, AID_ROOT, AID_ROOT, 0, "odm/etc/fs_config_files"},
5506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn};
5606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn#endif
5706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
5806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzynstatic void usage() {
5906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  fprintf(stderr,
6006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    "Generate binary content for fs_config_dirs (-D) and fs_config_files (-F)\n"
61256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    "from device-specific android_filesystem_config.h override.  Filter based\n"
62256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    "on a comma separated partition list (-P) whitelist or prefixed by a\n"
63256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    "minus blacklist.  Partitions are identified as path references to\n"
64256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    "<partition>/ or system/<partition>/\n\n"
65256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    "Usage: fs_config_generate -D|-F [-P list] [-o output-file]\n");
6606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn}
6706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
68256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn/* If tool switches to C++, use android-base/macros.h array_size() */
69256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn#ifndef ARRAY_SIZE /* popular macro */
70256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
71256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn#endif
72256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn
7306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzynint main(int argc, char** argv) {
74256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  const struct fs_path_config* pc;
75256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  const struct fs_path_config* end;
7606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  bool dir = false, file = false;
77256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  const char* partitions = NULL;
78256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  FILE* fp = stdout;
7906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  int opt;
80256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  static const char optstring[] = "DFP:ho:";
8106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
82256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  while ((opt = getopt(argc, argv, optstring)) != -1) {
83256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    switch (opt) {
8406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'D':
8506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (file) {
8606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Must specify only -D or -F\n");
8706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        usage();
8806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
8906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
9006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      dir = true;
9106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      break;
9206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'F':
9306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (dir) {
9406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Must specify only -F or -D\n");
9506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        usage();
9606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
9706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
9806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      file = true;
9906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      break;
100256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    case 'P':
101256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      if (partitions) {
102256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        fprintf(stderr, "Specify only one partition list\n");
103256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        usage();
104256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        exit(EXIT_FAILURE);
105256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      }
106256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      while (*optarg && isspace(*optarg)) ++optarg;
107256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      if (!optarg[0]) {
108256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        fprintf(stderr, "Partition list empty\n");
109256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        usage();
110256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        exit(EXIT_FAILURE);
111256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      }
112256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      if (!optarg[1]) {
113256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        fprintf(stderr, "Partition list too short \"%s\"\n", optarg);
114256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        usage();
115256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        exit(EXIT_FAILURE);
116256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      }
117256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      if ((optarg[0] == '-') && strchr(optstring, optarg[1]) && !optarg[2]) {
118256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        fprintf(stderr, "Partition list is a flag \"%s\"\n", optarg);
119256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        usage();
120256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        exit(EXIT_FAILURE);
121256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      }
122256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      partitions = optarg;
123256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      break;
12406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'o':
12506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (fp != stdout) {
12606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Specify only one output file\n");
12706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        usage();
12806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
12906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
1306024069f378dd95667c078d8360ed515116dd309Mark Salyzyn      fp = fopen(optarg, "wb");
13106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      if (fp == NULL) {
13206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        fprintf(stderr, "Can not open \"%s\"\n", optarg);
13306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn        exit(EXIT_FAILURE);
13406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      }
13506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      break;
13606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    case 'h':
13706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      usage();
13806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_SUCCESS);
13906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    default:
14006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      usage();
14106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_FAILURE);
14206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    }
14306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
14406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
145256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  if (optind < argc) {
146256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    fprintf(stderr, "Unknown non-argument \"%s\"\n", argv[optind]);
147256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    usage();
148256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    exit(EXIT_FAILURE);
149256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  }
150256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn
15106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  if (!file && !dir) {
15206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    fprintf(stderr, "Must specify either -F or -D\n");
15306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    usage();
15406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    exit(EXIT_FAILURE);
15506b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
15606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
15706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  if (dir) {
15806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    pc = android_device_dirs;
159256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    end = &android_device_dirs[ARRAY_SIZE(android_device_dirs)];
16006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  } else {
16106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    pc = android_device_files;
162256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    end = &android_device_files[ARRAY_SIZE(android_device_files)];
16306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
164256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn  for (; (pc < end) && pc->prefix; pc++) {
165256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    bool submit;
16606b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    char buffer[512];
16706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    ssize_t len = fs_config_generate(buffer, sizeof(buffer), pc);
16806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    if (len < 0) {
16906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      fprintf(stderr, "Entry too large\n");
17006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_FAILURE);
17106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    }
172256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    submit = true;
173256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    if (partitions) {
174256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      char* partitions_copy = strdup(partitions);
175256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      char* arg = partitions_copy;
176256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      char* sv = NULL; /* Do not leave uninitialized, NULL is known safe. */
177256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      /* Deal with case all iterated partitions are blacklists with no match */
178256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      bool all_blacklist_but_no_match = true;
179256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      submit = false;
180256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn
181256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      if (!partitions_copy) {
182256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        fprintf(stderr, "Failed to allocate a copy of %s\n", partitions);
183256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        exit(EXIT_FAILURE);
184256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      }
185256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      /* iterate through (officially) comma separated list of partitions */
186256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      while (!!(arg = strtok_r(arg, ",:; \t\n\r\f", &sv))) {
187256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        static const char system[] = "system/";
188256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        size_t plen;
189256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        bool blacklist = false;
190256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        if (*arg == '-') {
191256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          blacklist = true;
192256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          ++arg;
193256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        } else {
194256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          all_blacklist_but_no_match = false;
195256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        }
196256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        plen = strlen(arg);
197256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        /* deal with evil callers */
198256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        while (arg[plen - 1] == '/') {
199256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          --plen;
200256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        }
201256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        /* check if we have <partition>/ or /system/<partition>/ */
202256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        if ((!strncmp(pc->prefix, arg, plen) && (pc->prefix[plen] == '/')) ||
203256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn            (!strncmp(pc->prefix, system, strlen(system)) &&
204256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn             !strncmp(pc->prefix + strlen(system), arg, plen) &&
205256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn             (pc->prefix[strlen(system) + plen] == '/'))) {
206256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          all_blacklist_but_no_match = false;
207256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          /* we have a match !!! */
208256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          if (!blacklist) submit = true;
209256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn          break;
210256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        }
211256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn        arg = NULL;
212256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      }
213256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      free(partitions_copy);
214256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn      if (all_blacklist_but_no_match) submit = true;
215256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    }
216256d339413a54adeceb505f9d2f062856bcbba43Mark Salyzyn    if (submit && (fwrite(buffer, 1, len, fp) != (size_t)len)) {
21706b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      fprintf(stderr, "Write failure\n");
21806b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn      exit(EXIT_FAILURE);
21906b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn    }
22006b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  }
22106b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  fclose(fp);
22206b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn
22306b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn  return 0;
22406b91b9bcf4410d7b8c8c5e10a717671dd327c35Mark Salyzyn}
225