1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 static int delete_rule(const char *rule) {
38 if (!(x = strdup(rule)))
41 e = strchrnul(x+1, x[0]);
44 asprintf(&fn, "/proc/sys/fs/binfmt_misc/%s", x+1);
50 r = write_one_line_file(fn, "-1");
56 static int apply_rule(const char *rule) {
61 if ((r = write_one_line_file("/proc/sys/fs/binfmt_misc/register", rule)) < 0) {
62 log_error("Failed to add binary format: %s", strerror(-r));
69 static int apply_file(const char *path, bool ignore_enoent) {
75 if (!(f = fopen(path, "re"))) {
76 if (ignore_enoent && errno == ENOENT)
79 log_error("Failed to open file '%s', ignoring: %m", path);
87 if (!fgets(l, sizeof(l), f)) {
91 log_error("Failed to read file '%s', ignoring: %m", path);
101 if (strchr(COMMENTS, *p))
104 if ((k = apply_rule(p)) < 0 && r == 0)
114 static int scandir_filter(const struct dirent *d) {
117 if (ignore_file(d->d_name))
120 if (d->d_type != DT_REG &&
121 d->d_type != DT_LNK &&
122 d->d_type != DT_UNKNOWN)
125 return endswith(d->d_name, ".conf");
128 static int apply_tree(const char *path) {
129 struct dirent **de = NULL;
132 if ((n = scandir(path, &de, scandir_filter, alphasort)) < 0) {
137 log_error("Failed to enumerate %s files: %m", path);
141 for (i = 0; i < n; i++) {
145 k = asprintf(&fn, "%s/%s", path, de[i]->d_name);
149 log_error("Failed to allocate file name.");
156 if ((k = apply_file(fn, true)) < 0 && r == 0)
165 int main(int argc, char *argv[]) {
169 log_error("This program expects one or no arguments.");
173 log_set_target(LOG_TARGET_AUTO);
174 log_parse_environment();
178 r = apply_file(argv[1], false);
180 /* Flush out all rules */
181 write_one_line_file("/proc/sys/fs/binfmt_misc/status", "-1");
183 r = apply_tree("/etc/binfmt.d");
186 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;