]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/binfmt/binfmt.c
journald: proceed even if some sockets are unknown
[thirdparty/systemd.git] / src / binfmt / binfmt.c
CommitLineData
151b190e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
151b190e
LP
11 (at your option) any later version.
12
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
5430f7f2 16 Lesser General Public License for more details.
151b190e 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
151b190e
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdlib.h>
23#include <stdbool.h>
24#include <errno.h>
25#include <string.h>
26#include <stdio.h>
27#include <limits.h>
db1413d7 28#include <stdarg.h>
fabe5c0e 29#include <getopt.h>
151b190e
LP
30
31#include "log.h"
db1413d7
KS
32#include "hashmap.h"
33#include "strv.h"
151b190e 34#include "util.h"
2c21044f 35#include "conf-files.h"
a5c32cff 36#include "fileio.h"
eb9da376 37#include "build.h"
151b190e 38
fabe5c0e
LP
39static const char conf_file_dirs[] =
40 "/etc/binfmt.d\0"
41 "/run/binfmt.d\0"
42 "/usr/local/lib/binfmt.d\0"
43 "/usr/lib/binfmt.d\0"
44#ifdef HAVE_SPLIT_USR
45 "/lib/binfmt.d\0"
46#endif
47 ;
48
151b190e 49static int delete_rule(const char *rule) {
fabe5c0e
LP
50 _cleanup_free_ char *x = NULL, *fn = NULL;
51 char *e;
151b190e
LP
52
53 assert(rule[0]);
54
fabe5c0e
LP
55 x = strdup(rule);
56 if (!x)
14212119 57 return log_oom();
151b190e
LP
58
59 e = strchrnul(x+1, x[0]);
60 *e = 0;
61
fabe5c0e 62 fn = strappend("/proc/sys/fs/binfmt_misc/", x+1);
151b190e 63 if (!fn)
14212119 64 return log_oom();
151b190e 65
574d5f2d 66 return write_string_file(fn, "-1");
151b190e
LP
67}
68
69static int apply_rule(const char *rule) {
70 int r;
71
72 delete_rule(rule);
73
574d5f2d 74 r = write_string_file("/proc/sys/fs/binfmt_misc/register", rule);
fabe5c0e 75 if (r < 0) {
151b190e
LP
76 log_error("Failed to add binary format: %s", strerror(-r));
77 return r;
78 }
79
80 return 0;
81}
82
83static int apply_file(const char *path, bool ignore_enoent) {
fabe5c0e
LP
84 _cleanup_fclose_ FILE *f = NULL;
85 int r;
151b190e
LP
86
87 assert(path);
88
4cf7ea55 89 r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
fabe5c0e
LP
90 if (r < 0) {
91 if (ignore_enoent && r == -ENOENT)
151b190e
LP
92 return 0;
93
fabe5c0e
LP
94 log_error("Failed to open file '%s', ignoring: %s", path, strerror(-r));
95 return r;
151b190e
LP
96 }
97
9f6445e3 98 log_debug("apply: %s", path);
fabe5c0e 99 for (;;) {
151b190e
LP
100 char l[LINE_MAX], *p;
101 int k;
102
103 if (!fgets(l, sizeof(l), f)) {
104 if (feof(f))
105 break;
106
107 log_error("Failed to read file '%s', ignoring: %m", path);
fabe5c0e 108 return -errno;
151b190e
LP
109 }
110
111 p = strstrip(l);
151b190e
LP
112 if (!*p)
113 continue;
d3b6d0c2 114 if (strchr(COMMENTS "\n", *p))
151b190e
LP
115 continue;
116
fabe5c0e
LP
117 k = apply_rule(p);
118 if (k < 0 && r == 0)
151b190e
LP
119 r = k;
120 }
121
151b190e
LP
122 return r;
123}
124
601185b4 125static void help(void) {
fabe5c0e
LP
126 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
127 "Registers binary formats.\n\n"
eb9da376 128 " -h --help Show this help\n"
601185b4
ZJS
129 " --version Show package version\n"
130 , program_invocation_short_name);
fabe5c0e
LP
131}
132
133static int parse_argv(int argc, char *argv[]) {
134
eb9da376
LP
135 enum {
136 ARG_VERSION = 0x100,
137 };
138
fabe5c0e
LP
139 static const struct option options[] = {
140 { "help", no_argument, NULL, 'h' },
eb9da376
LP
141 { "version", no_argument, NULL, ARG_VERSION },
142 {}
fabe5c0e
LP
143 };
144
145 int c;
146
147 assert(argc >= 0);
148 assert(argv);
149
601185b4 150 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
fabe5c0e
LP
151
152 switch (c) {
153
154 case 'h':
601185b4
ZJS
155 help();
156 return 0;
eb9da376
LP
157
158 case ARG_VERSION:
159 puts(PACKAGE_STRING);
160 puts(SYSTEMD_FEATURES);
fabe5c0e
LP
161 return 0;
162
163 case '?':
164 return -EINVAL;
165
166 default:
eb9da376 167 assert_not_reached("Unhandled option");
fabe5c0e 168 }
fabe5c0e
LP
169
170 return 1;
171}
172
151b190e 173int main(int argc, char *argv[]) {
fabe5c0e
LP
174 int r, k;
175
176 r = parse_argv(argc, argv);
177 if (r <= 0)
178 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
151b190e 179
151b190e
LP
180 log_set_target(LOG_TARGET_AUTO);
181 log_parse_environment();
182 log_open();
183
4c12626c
LP
184 umask(0022);
185
fabe5c0e 186 r = 0;
13317670 187
fabe5c0e
LP
188 if (argc > optind) {
189 int i;
13317670 190
fabe5c0e 191 for (i = optind; i < argc; i++) {
170dcb7b 192 k = apply_file(argv[i], false);
13317670
LP
193 if (k < 0 && r == 0)
194 r = k;
195 }
db1413d7 196 } else {
fabe5c0e
LP
197 _cleanup_strv_free_ char **files = NULL;
198 char **f;
db1413d7 199
fabe5c0e 200 r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
44143309
KS
201 if (r < 0) {
202 log_error("Failed to enumerate binfmt.d files: %s", strerror(-r));
203 goto finish;
204 }
151b190e 205
13317670 206 /* Flush out all rules */
574d5f2d 207 write_string_file("/proc/sys/fs/binfmt_misc/status", "-1");
13317670 208
db1413d7 209 STRV_FOREACH(f, files) {
db1413d7
KS
210 k = apply_file(*f, true);
211 if (k < 0 && r == 0)
212 r = k;
213 }
db1413d7 214 }
fabe5c0e 215
44143309 216finish:
151b190e
LP
217 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
218}