3 ### Replace common tools in foreign chroots with native versions
5 ### (c) 2018 Mark Wooding
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the distorted.org.uk chroot maintenance tools.
12 ### distorted-chroot is free software: you can redistribute it and/or
13 ### modify it under the terms of the GNU General Public License as
14 ### published by the Free Software Foundation; either version 2 of the
15 ### License, or (at your option) any later version.
17 ### distorted-chroot is distributed in the hope that it will be useful,
18 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ### General Public License for more details.
22 ### You should have received a copy of the GNU General Public License
23 ### along with distorted-chroot. If not, write to the Free Software
24 ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 . state/config.sh # @@@config@@@
29 ## Parse the command-line.
31 case $# in 2) ;; *) badp=t ;; esac
32 case $badp in t) echo >&2 "usage: $0 DIST ARCH"; exit 2 ;; esac
35 ## Figure out of all the architecture names.
36 mymulti=$(dpkg-architecture -a$TOOLSARCH -qDEB_HOST_MULTIARCH)
37 gnuarch=$(dpkg-architecture -A$a -qDEB_TARGET_GNU_TYPE)
39 for fa in $FOREIGN_ARCHS; do
42 eval qarch=\$${a}_QEMUARCH qhost=\$${a}_QEMUHOST
47 nil,* | *,nil) echo >&2 "$0: not a foreign architecture"; exit 2 ;;
50 ## Make sure we have the tools we need.
51 crossdir=/usr/local.schroot/cross/$d-$TOOLSARCH
52 my_crossdir=$LOCAL/${crossdir#/usr/local.schroot/}
53 qemudir=/usr/local.schroot/cross/$d-$qhost/QEMU
54 my_qemudir=$LOCAL/${qemudir#/usr/local.schroot/}
55 if ! [ -d $my_crossdir ]; then
56 echo 2>&1 "$0: no tree for \`$d-$TOOLSARCH'"; exit 2
58 if ! [ -d $my_qemudir ]; then
59 echo 2>&1 "$0: no tree for \`$d-$qhost'"; exit 2
62 ## Open a session to the target chroot.
63 sess=$(schroot -bcsource:$LVPREFIX$d-$a)
64 root=/schroot/$sess/fs
66 ## Abuse `/mnt/' as a temporary staging area. This saves us from clobbering
67 ## the chroot with weird directories.
68 schroot -uroot -rc$sess -- sh -ec '
69 if ! mountpoint -q /mnt; then
70 mount -ttmpfs -omode=700,uid=0,gid=0 private /mnt
73 ## Work through all of the tools we're interested in, to decide what we need
74 ## to do with it. Make lists:
76 ## * `DIVERT.want' lists all of the filenames which need dpkg diversions to
77 ## prevent foreign versions of the tools from clobbering our native
80 ## * `LINK'.want' lists all of the paths which need symbolic links into the
81 ## cross-tools trees, together with the link destinations.
82 { echo $qemudir/qemu-$qarch-static
83 echo $crossdir/lib/$mymulti
84 echo $crossdir/usr/lib/$mymulti
85 echo $crossdir/usr/lib/gcc-cross
86 find $my_crossdir $my_crossdir/TOOLCHAIN/$gnuarch \
87 \( \( -path "*/QEMU" -o -path "*/TOOLCHAIN" -o \
88 -path "*/lib/$mymulti" -o \
89 -path "*/lib/gcc-cross" \) -prune \) -o \
90 \( ! -type d -print \)
91 } | sed "s
\a^$LOCAL/
\a/usr/local.schroot/
\a" | while read t; do
94 s=/usr/bin/${t#$qemudir/} ;;
95 $crossdir/TOOLCHAIN/$gnuarch/*)
96 s=/usr/bin/${t#$crossdir/TOOLCHAIN/$gnuarch/} ;;
100 if [ -L $t ]; then t=$(readlink $t); fi
101 if [ -d $t ]; then act=LINK; else act=DIVERT; fi
103 done >$root/mnt/ALL.want
104 sed -n '/^DIVERT \(.*\) .*$/s//\1/p' $root/mnt/ALL.want | \
105 sort >$root/mnt/DIVERT.want
106 sed -n '/^\(DIVERT\|LINK\) /s///p' $root/mnt/ALL.want | \
107 sort >$root/mnt/LINK.want
109 ## Make a list, `DIVERT.have', of paths which already have diversions, and a
110 ## list `LINK.have' of symbolic links into the cross-tools trees. The
111 ## layouts of these files match the `.want' files we just made.
112 schroot -uroot -rc$sess -- sh -ec '
114 sed -n "/^diversion of \(.*\) to .* by install-cross-tools\$/s//\1/p" | \
115 sort >/mnt/DIVERT.have
116 { find / -xdev -lname "/usr/local.schroot/cross/*" -printf "%p %l\n"
118 if ! [ -L "$s" ]; then continue; fi
120 case $t in /usr/local.schroot/cross/*) continue ;; esac
123 } | sort >/mnt/LINK.have'
125 ## Add diversions for the paths which need one, but don't have one. There's
126 ## a hack here because the `--no-rename' option was required in the same
127 ## version in which is was introduced, so there's no single incantation that
128 ## will work across the boundary.
129 schroot -uroot -rc$sess -- sh -ec '
132 if dpkg-divert >/dev/null 2>&1 --no-rename --help
133 then no_rename=--no-rename
137 comm -13 /mnt/DIVERT.have /mnt/DIVERT.want | while read i; do
138 dpkg-divert --package "install-cross-tools" $no_rename \
139 --divert "$i.$a" --add "$i"
142 ## Go through each diverted tool, and, if it hasn't been moved aside, then
143 ## /link/ it across now. If we rename it, then the chroot will stop working
144 ## -- which is why we didn't allow `dpkg-divert' to do the rename. We can
145 ## tell a tool that hasn't been moved, because it's a symlink into one of the
148 if [ -e $root$i ] && ! [ -e $root$i.$a ]; then
149 if [ -L $root$i ]; then
150 t=$(readlink $root$i)
152 $crossdir/* | $qemudir/* | /usr/local.schroot/qemu/*) continue ;;
154 if [ -L $crossdir$i ]; then
155 u=$(readlink $crossdir$i)
156 case $t in "$u") continue ;; esac
159 echo >&2 "$0: preserve old $i"
160 ln $root$i $root$i.$a
162 done <$root/mnt/DIVERT.want
164 ## Update all of the symbolic links which are currently wrong: add links
165 ## which are missing, delete ones which are obsolete, and update ones which
166 ## have the wrong target.
167 join -j1 -a1 -a2 -e- -o"0 1.2 2.2" \
168 $root/mnt/LINK.have $root/mnt/LINK.want |
169 while read s t0 t1; do
175 echo >&2 "$0: remove obsolete link $s -> $t0"
179 case $s in */*) mkdir -p $root${s%/*} ;; esac
181 ln -s $t1 $root$s.new
182 echo >&2 "$0: link $s -> $t1"
183 mv -T $root$s.new $root$s
188 ## Remove diversions from paths which don't need them any more. Here it's
189 ## safe to rename, because either the tool isn't there, in which case it
190 ## obviously wasn't important, or it is, and `dpkg-divert' will atomically
191 ## replace our link with the foreign version.
192 schroot -uroot -rc$sess -- sh -ec '
194 comm -23 /mnt/DIVERT.have /mnt/DIVERT.want | while read i; do
195 dpkg-divert --package "install-cross-tools" --rename \
196 --divert "$i.$a" --remove "$i"
199 ## Close the session.
202 ###----- That's all, folks --------------------------------------------------