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 |
warn_invalid() { |
14 |
printf "binfmt: invalid entry on line %d of \`%s'\n" "$LINENUM" "$FILE" |
15 |
error=$(( error+1 )) |
16 |
} >&2 |
17 |
|
18 |
# parse the command line |
19 |
while [ $# -gt 0 ]; do |
20 |
case $1 in |
21 |
--verbose) VERBOSE=1 ;; |
22 |
--dryrun|--dry-run) DRYRUN=1 ;; |
23 |
esac |
24 |
shift |
25 |
done |
26 |
|
27 |
error=0 LINENUM=0 |
28 |
|
29 |
# The hardcoding of these paths is intentional; we are following the |
30 |
# systemd spec. |
31 |
binfmt_dirs='/usr/lib/binfmt.d/ /run/binfmt.d/ /etc/binfmt.d/' |
32 |
binfmt_basenames='' |
33 |
binfmt_d='' |
34 |
# Build a list of sorted unique basenames |
35 |
# directories declared later in the binfmt_d list will override earlier |
36 |
# directories, on a per file basename basis. |
37 |
# `/run/binfmt.d/foo.conf' supersedes `/usr/lib/binfmt.d/foo.conf'. |
38 |
# `/run/binfmt.d/foo.conf' will always be read after `/etc/binfmt.d/bar.conf' |
39 |
for d in ${binfmt_dirs} ; do |
40 |
[ -d $d ] && for f in ${d}/*.conf ; do |
41 |
case "${f##*/}" in |
42 |
systemd.conf|systemd-*.conf) continue;; |
43 |
esac |
44 |
[ -f $f ] && binfmt_basenames="${binfmt_basenames}\n${f##*/}" |
45 |
done # for f in ${d} |
46 |
done # for d in ${binfmt_dirs} |
47 |
binfmt_basenames="$(printf "${binfmt_basenames}\n" | sort -u )" |
48 |
|
49 |
for b in $binfmt_basenames ; do |
50 |
real_f='' |
51 |
for d in $binfmt_dirs ; do |
52 |
f=${d}/${b} |
53 |
[ -f "${f}" ] && real_f=$f |
54 |
done |
55 |
[ -f "${real_f}" ] && binfmt_d="${binfmt_d} ${real_f}" |
56 |
done |
57 |
|
58 |
# loop through the gathered fragments, sorted globally by filename. |
59 |
# `/run/binfmt.d/foo.conf' will always be read after `/etc/binfmt.d/bar.conf' |
60 |
for FILE in $binfmt_d ; do |
61 |
LINENUM=0 |
62 |
|
63 |
### FILE FORMAT ### |
64 |
# See https://www.kernel.org/doc/Documentation/binfmt_misc.txt |
65 |
|
66 |
while read line; do |
67 |
LINENUM=$(( LINENUM+1 )) |
68 |
|
69 |
case $line in |
70 |
\#*) continue ;; |
71 |
\;*) continue ;; |
72 |
esac |
73 |
|
74 |
[ -n "$VERBOSE" -o -n "$DRYRUN" ]] && echo $line |
75 |
[ -z "$DRYRUN" ] && echo "${line}" > /proc/sys/fs/binfmt_misc/register |
76 |
rc=$? |
77 |
if [ -z "${DRYRUN}" ]; then |
78 |
[ $rc -ne 0 ] && warn_invalid |
79 |
fi |
80 |
done <$FILE |
81 |
done |
82 |
|
83 |
exit $error |
84 |
|
85 |
# vim: set ts=2 sw=2 sts=2 noet ft=sh: |