]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/binfmt/binfmt.c
analyze: add --root option for cat-config
[thirdparty/systemd.git] / src / binfmt / binfmt.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
151b190e
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
151b190e
LP
6***/
7
151b190e 8#include <errno.h>
fabe5c0e 9#include <getopt.h>
3f6fd1ba
LP
10#include <limits.h>
11#include <stdbool.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
151b190e 15
b5efdb8a 16#include "alloc-util.h"
3f6fd1ba 17#include "conf-files.h"
a0f29c76 18#include "def.h"
3ffd4af2 19#include "fd-util.h"
3f6fd1ba 20#include "fileio.h"
151b190e 21#include "log.h"
07630cea 22#include "string-util.h"
db1413d7 23#include "strv.h"
151b190e
LP
24#include "util.h"
25
75eb6154 26static const char conf_file_dirs[] = CONF_PATHS_NULSTR("binfmt.d");
fabe5c0e 27
151b190e 28static int delete_rule(const char *rule) {
fabe5c0e
LP
29 _cleanup_free_ char *x = NULL, *fn = NULL;
30 char *e;
151b190e
LP
31
32 assert(rule[0]);
33
fabe5c0e
LP
34 x = strdup(rule);
35 if (!x)
14212119 36 return log_oom();
151b190e
LP
37
38 e = strchrnul(x+1, x[0]);
39 *e = 0;
40
fabe5c0e 41 fn = strappend("/proc/sys/fs/binfmt_misc/", x+1);
151b190e 42 if (!fn)
14212119 43 return log_oom();
151b190e 44
4c1fc3e4 45 return write_string_file(fn, "-1", 0);
151b190e
LP
46}
47
48static int apply_rule(const char *rule) {
49 int r;
50
51 delete_rule(rule);
52
4c1fc3e4 53 r = write_string_file("/proc/sys/fs/binfmt_misc/register", rule, 0);
23bbb0de
MS
54 if (r < 0)
55 return log_error_errno(r, "Failed to add binary format: %m");
151b190e
LP
56
57 return 0;
58}
59
60static int apply_file(const char *path, bool ignore_enoent) {
fabe5c0e
LP
61 _cleanup_fclose_ FILE *f = NULL;
62 int r;
151b190e
LP
63
64 assert(path);
65
4cf7ea55 66 r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
fabe5c0e
LP
67 if (r < 0) {
68 if (ignore_enoent && r == -ENOENT)
151b190e
LP
69 return 0;
70
23bbb0de 71 return log_error_errno(r, "Failed to open file '%s', ignoring: %m", path);
151b190e
LP
72 }
73
9f6445e3 74 log_debug("apply: %s", path);
fabe5c0e 75 for (;;) {
151b190e
LP
76 char l[LINE_MAX], *p;
77 int k;
78
79 if (!fgets(l, sizeof(l), f)) {
80 if (feof(f))
81 break;
82
e1427b13 83 return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path);
151b190e
LP
84 }
85
86 p = strstrip(l);
151b190e
LP
87 if (!*p)
88 continue;
d3b6d0c2 89 if (strchr(COMMENTS "\n", *p))
151b190e
LP
90 continue;
91
fabe5c0e
LP
92 k = apply_rule(p);
93 if (k < 0 && r == 0)
151b190e
LP
94 r = k;
95 }
96
151b190e
LP
97 return r;
98}
99
601185b4 100static void help(void) {
fabe5c0e
LP
101 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
102 "Registers binary formats.\n\n"
eb9da376 103 " -h --help Show this help\n"
601185b4
ZJS
104 " --version Show package version\n"
105 , program_invocation_short_name);
fabe5c0e
LP
106}
107
108static int parse_argv(int argc, char *argv[]) {
109
eb9da376
LP
110 enum {
111 ARG_VERSION = 0x100,
112 };
113
fabe5c0e
LP
114 static const struct option options[] = {
115 { "help", no_argument, NULL, 'h' },
eb9da376
LP
116 { "version", no_argument, NULL, ARG_VERSION },
117 {}
fabe5c0e
LP
118 };
119
120 int c;
121
122 assert(argc >= 0);
123 assert(argv);
124
601185b4 125 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
fabe5c0e
LP
126
127 switch (c) {
128
129 case 'h':
601185b4
ZJS
130 help();
131 return 0;
eb9da376
LP
132
133 case ARG_VERSION:
3f6fd1ba 134 return version();
fabe5c0e
LP
135
136 case '?':
137 return -EINVAL;
138
139 default:
eb9da376 140 assert_not_reached("Unhandled option");
fabe5c0e 141 }
fabe5c0e
LP
142
143 return 1;
144}
145
151b190e 146int main(int argc, char *argv[]) {
fabe5c0e
LP
147 int r, k;
148
149 r = parse_argv(argc, argv);
150 if (r <= 0)
151 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
151b190e 152
151b190e
LP
153 log_set_target(LOG_TARGET_AUTO);
154 log_parse_environment();
155 log_open();
156
4c12626c
LP
157 umask(0022);
158
fabe5c0e 159 r = 0;
13317670 160
fabe5c0e
LP
161 if (argc > optind) {
162 int i;
13317670 163
fabe5c0e 164 for (i = optind; i < argc; i++) {
170dcb7b 165 k = apply_file(argv[i], false);
13317670
LP
166 if (k < 0 && r == 0)
167 r = k;
168 }
db1413d7 169 } else {
fabe5c0e
LP
170 _cleanup_strv_free_ char **files = NULL;
171 char **f;
db1413d7 172
b5084605 173 r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
44143309 174 if (r < 0) {
da927ba9 175 log_error_errno(r, "Failed to enumerate binfmt.d files: %m");
44143309
KS
176 goto finish;
177 }
151b190e 178
13317670 179 /* Flush out all rules */
ad118bda 180 write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", 0);
13317670 181
db1413d7 182 STRV_FOREACH(f, files) {
db1413d7
KS
183 k = apply_file(*f, true);
184 if (k < 0 && r == 0)
185 r = k;
186 }
db1413d7 187 }
fabe5c0e 188
44143309 189finish:
151b190e
LP
190 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
191}