-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcopy_exe
executable file
·159 lines (139 loc) · 3.59 KB
/
copy_exe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/bash
libdir="/lib"
include_man=1
while test -n "$1";do
case "$1" in
-m)
include_man=""
;;
-b)
shift
bindir="$1"
;;
-l)
shift
libdir="$1"
;;
-p)
shift
libpath="$1"
;;
*)
break
;;
esac
shift
done
dst="$1"
shift
if test -z "$dst";then
echo "Usage: $0 [ -m ] [ -b bindir ] [ -l libdir ] [ -p libpath ] destroot [executable...]"
echo "Where:"
echo " -m exclude manpages"
echo " destroot - root directory of new files"
echo " bindir - program files path in destroot [default: original location]"
echo " libdir - library path in destroot [default: /lib]"
echo " libpath - additional library path (not related to destroot)"
exit 1
fi
libdirs="/lib /usr/lib /lib/systemd $(ldconfig -p | sed -ne '/=>/{s@.*=> \(.*\)/.*@\1@;p}' | sort -u)"
mkdir -p "$dst$libdir"
exit_code=0
get_missing_reqs() {
reqs=""
for tgt;do
read hdr opts <"$tgt"
case "$hdr" in
?ELF*)
local interp="$(objcopy -j .interp "$1" -O binary /proc/self/fd/1 | tr -d \\0)"
test -z "$interp" || need_copy "$interp" "$dst" $libpath && interpreters="$interpreters $interp"
reqs="$reqs `get_missing_elf_reqs "$tgt"`" ;;
"#!"*)
local interp="${hdr#\#\!}"
if need_copy "$interp" "$dst";then interpreters="$interpreters $interp";fi
;;
*) echo "Unknown program $tgt - $hdr" >&2 ;;
esac
done
}
get_missing_elf_reqs() {
local check lib s3 s4 arch=""
objdump -p "$1" | while read check lib s3 s4;do
if test "$lib $s3" == "file format";then
arch="$s4"
continue
fi
test "$check" == "NEEDED" || continue
need_copy "$lib" "$dst$libdir" $libpath || continue
if need_copy ${arch:+-a "$arch"} -v "$lib" $libdirs;then
echo "ERROR: Cannot find $lib" >&2
exit_code=1
fi
done
}
# copy only if not existing: name,dirnames
need_copy() {
local arch
test "$1" != "-a" || { arch="$2"; shift 2; }
test "$1" != "-v" || { local verbose="1"; shift; }
local src="$1"
local name="`basename "$src"`"
shift
local missing="yes"
for testdir;do
test ! -e "$testdir/$name" || {
test "$src" != "$name" -a -e "$src" -a "$src" -nt "$testdir/$name" && continue
test -z "$arch" -o "$(objdump -p "$testdir/$name" | grep -o "file format .*" | cut -f3 -d" ")" = "$arch" || continue
missing="no"
test -z "$verbose" || echo "$testdir/$name"
break
}
done
test "$missing" = "yes"
}
copy_exe() {
local src prog_dir dst_bin
if test -e "$1";then src="$1"; else src="`type -path "$1"`";fi
if test -z "$src";then
echo "ERROR: $1 not found"
exit_code=1
fi
if test -n "$bindir";then dst_bin="$bindir";else
prog_dir="`dirname "$src"`"
test "$prog_dir" != "." || prog_dir="/bin"
dst_bin="$dst/$prog_dir"
fi
test -d "$dst_bin" || mkdir -p "$dst_bin"
local name="`basename "$src"`"
if need_copy "$src" "$dst_bin" $libpath;then
if test -L "$dst_bin/$name";then rm "$dst_bin/$name";fi
cp -v "$src" "$dst_bin"
if test -n "$include_man";then
manpages=/usr/share/man/man[18]/$name.*
for manpage in $manpages;do
if test -e "$manpage";then
cp -v --parents "$manpage" "$dst"
fi
done
fi
get_missing_reqs "$src"
while test -n "$reqs";do
for lib in $reqs; do
cp -v "$lib" "$dst$libdir"
done
get_missing_reqs $reqs
done
fi
}
for prog;do
copy_exe "$prog"
done
bindir=""
while test -n "$interpreters";do
intlist="$interpreters"
interpreters=""
for interp in $intlist;do
copy_exe "$interp"
done
done
exit $exit_code