Line 0
Link Here
|
0 |
- |
1 |
#!/bin/sh |
|
|
2 |
# This is a reimplementation of the systemd binfmt.d code to register |
3 |
# misc binary formats with the kernel. |
4 |
# |
5 |
# Copyright (c) 2015 William Hubbs |
6 |
# Released under the 2-clause BSD license. |
7 |
# |
8 |
# See the binfmt.d manpage as well: |
9 |
# http://0pointer.de/public/systemd-man/binfmt.d.html |
10 |
# This script should match the manpage as of 2015/03/31 |
11 |
# |
12 |
|
13 |
warninvalid() { |
14 |
printf "binfmt: invalid entry on line %d of \`%s'\n" "$LINENUM" "$FILE" |
15 |
error=$(( error+1 )) |
16 |
} >&2 |
17 |
|
18 |
dryrun_or_real() { |
19 |
local dry= |
20 |
[ -n "$DRYRUN" ] && dry=echo |
21 |
$dry "$@" |
22 |
} |
23 |
|
24 |
# parse the command line |
25 |
while [ $# -gt 0 ]; do |
26 |
case $1 in |
27 |
--verbose) VERBOSE=1 ;; |
28 |
--dryrun|--dry-run) DRYRUN=1 ;; |
29 |
esac |
30 |
shift |
31 |
done |
32 |
|
33 |
error=0 LINENUM=0 |
34 |
|
35 |
# The hardcoding of these paths is intentional; we are following the |
36 |
# systemd spec. |
37 |
binfmt_dirs='/usr/lib/binfmt.d/ /run/binfmt.d/ /etc/binfmt.d/' |
38 |
binfmt_basenames='' |
39 |
binfmt_d='' |
40 |
# Build a list of sorted unique basenames |
41 |
# directories declared later in the binfmt_d list will override earlier |
42 |
# directories, on a per file basename basis. |
43 |
# `/run/binfmt.d/foo.conf' supersedes `/usr/lib/binfmt.d/foo.conf'. |
44 |
# `/run/binfmt.d/foo.conf' will always be read after `/etc/binfmt.d/bar.conf' |
45 |
for d in ${binfmt_dirs} ; do |
46 |
[ -d $d ] && for f in ${d}/*.conf ; do |
47 |
case "${f##*/}" in |
48 |
systemd.conf|systemd-*.conf) continue;; |
49 |
esac |
50 |
[ -f $f ] && binfmt_basenames="${binfmt_basenames}\n${f##*/}" |
51 |
done # for f in ${d} |
52 |
done # for d in ${binfmt_dirs} |
53 |
binfmt_basenames="$(printf "${binfmt_basenames}\n" | sort -u )" |
54 |
|
55 |
for b in $binfmt_basenames ; do |
56 |
real_f='' |
57 |
for d in $binfmt_dirs ; do |
58 |
f=${d}/${b} |
59 |
[ -f "${f}" ] && real_f=$f |
60 |
done |
61 |
[ -f "${real_f}" ] && binfmt_d="${binfmt_d} ${real_f}" |
62 |
done |
63 |
|
64 |
# loop through the gathered fragments, sorted globally by filename. |
65 |
# `/run/binfmt.d/foo.conf' will always be read after `/etc/binfmt.d/bar.conf' |
66 |
for FILE in $binfmt_d ; do |
67 |
LINENUM=0 |
68 |
|
69 |
### FILE FORMAT ### |
70 |
# See https://www.kernel.org/doc/Documentation/binfmt_misc.txt |
71 |
|
72 |
while read line; do |
73 |
LINENUM=$(( LINENUM+1 )) |
74 |
|
75 |
case $line in |
76 |
\#*) continue ;; |
77 |
\;*) continue ;; |
78 |
esac |
79 |
|
80 |
[ -n "$VERBOSE" ] && echo $line |
81 |
dryrun_or_real echo "${line}" > /proc/sys/fs/binfmt_misc/register |
82 |
rc=$? |
83 |
if [ -z "${DRYRUN}" ]; then |
84 |
if [ $rc -ne 0 ]; then |
85 |
error=$((error + 1)) |
86 |
warninvalid |
87 |
fi |
88 |
fi |
89 |
done <$FILE |
90 |
done |
91 |
|
92 |
exit $error |
93 |
|
94 |
# vim: set ts=2 sw=2 sts=2 noet ft=sh: |