From: Mark Wooding Date: Thu, 19 Sep 2019 23:36:48 +0000 (+0100) Subject: Kill the old chroot-maintenance tools. X-Git-Url: https://git.distorted.org.uk/~mdw/distorted-chroot/commitdiff_plain/d830630af96cfb510381c73d9462121384484c4f Kill the old chroot-maintenance tools. `chroot-maint' has replaced all three of them. --- diff --git a/Makefile b/Makefile index 7e622e9..72299a7 100644 --- a/Makefile +++ b/Makefile @@ -419,9 +419,7 @@ $(PYMODULES): $(STATE)/lib/python/%.so: $$(call c-object,$$($$*_SOURCES)) ### Scripts. SCRIPTS += chroot-maint -SCRIPTS += mkbuildchroot SCRIPTS += mkchrootconf -SCRIPTS += install-cross-tools update-cross-tools SUBST_SCRIPTS = $(addprefix $(STATE)/bin/,$(SCRIPTS)) all:: $(SUBST_SCRIPTS) diff --git a/bin/install-cross-tools b/bin/install-cross-tools deleted file mode 100755 index b985551..0000000 --- a/bin/install-cross-tools +++ /dev/null @@ -1,202 +0,0 @@ -#! /bin/sh -e -### -### Replace common tools in foreign chroots with native versions -### -### (c) 2018 Mark Wooding -### - -###----- Licensing notice --------------------------------------------------- -### -### This file is part of the distorted.org.uk chroot maintenance tools. -### -### distorted-chroot is free software: you can redistribute it and/or -### modify it under the terms of the GNU General Public License as -### published by the Free Software Foundation; either version 2 of the -### License, or (at your option) any later version. -### -### distorted-chroot is distributed in the hope that it will be useful, -### but WITHOUT ANY WARRANTY; without even the implied warranty of -### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -### General Public License for more details. -### -### You should have received a copy of the GNU General Public License -### along with distorted-chroot. If not, write to the Free Software -### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -### USA. - -. state/config.sh # @@@config@@@ - -## Parse the command-line. -badp=nil -case $# in 2) ;; *) badp=t ;; esac -case $badp in t) echo >&2 "usage: $0 DIST ARCH"; exit 2 ;; esac -d=$1 a=$2 - -## Figure out of all the architecture names. -mymulti=$(dpkg-architecture -a$TOOLSARCH -qDEB_HOST_MULTIARCH) -gnuarch=$(dpkg-architecture -A$a -qDEB_TARGET_GNU_TYPE) -qarch=nil qhost=nil -for fa in $FOREIGN_ARCHS; do - case $fa in - "$a") - eval qarch=\$${a}_QEMUARCH qhost=\$${a}_QEMUHOST - break ;; - esac -done -case $qarch,$qhost in - nil,* | *,nil) echo >&2 "$0: not a foreign architecture"; exit 2 ;; -esac - -## Make sure we have the tools we need. -crossdir=/usr/local.schroot/cross/$d-$TOOLSARCH -my_crossdir=$LOCAL/${crossdir#/usr/local.schroot/} -qemudir=/usr/local.schroot/cross/$d-$qhost/QEMU -my_qemudir=$LOCAL/${qemudir#/usr/local.schroot/} -if ! [ -d $my_crossdir ]; then - echo 2>&1 "$0: no tree for \`$d-$TOOLSARCH'"; exit 2 -fi -if ! [ -d $my_qemudir ]; then - echo 2>&1 "$0: no tree for \`$d-$qhost'"; exit 2 -fi - -## Open a session to the target chroot. -sess=$(schroot -bcsource:$LVPREFIX$d-$a) -root=/schroot/$sess/fs - -## Abuse `/mnt/' as a temporary staging area. This saves us from clobbering -## the chroot with weird directories. -schroot -uroot -rc$sess -- sh -ec ' - if ! mountpoint -q /mnt; then - mount -ttmpfs -omode=700,uid=0,gid=0 private /mnt - fi' - -## Work through all of the tools we're interested in, to decide what we need -## to do with it. Make lists: -## -## * `DIVERT.want' lists all of the filenames which need dpkg diversions to -## prevent foreign versions of the tools from clobbering our native -## versions. -## -## * `LINK'.want' lists all of the paths which need symbolic links into the -## cross-tools trees, together with the link destinations. -{ echo $qemudir/qemu-$qarch-static - echo $crossdir/lib/$mymulti - echo $crossdir/usr/lib/$mymulti - echo $crossdir/usr/lib/gcc-cross - find $my_crossdir $my_crossdir/TOOLCHAIN/$gnuarch \ - \( \( -path "*/QEMU" -o -path "*/TOOLCHAIN" -o \ - -path "*/lib/$mymulti" -o \ - -path "*/lib/gcc-cross" \) -prune \) -o \ - \( ! -type d -print \) -} | sed "s^$LOCAL//usr/local.schroot/" | while read t; do - case $t in - $qemudir/*) - s=/usr/bin/${t#$qemudir/} ;; - $crossdir/TOOLCHAIN/$gnuarch/*) - s=/usr/bin/${t#$crossdir/TOOLCHAIN/$gnuarch/} ;; - *) - s=${t#$crossdir} ;; - esac - if [ -L $t ]; then t=$(readlink $t); fi - if [ -d $t ]; then act=LINK; else act=DIVERT; fi - echo $act $s $t -done >$root/mnt/ALL.want -sed -n '/^DIVERT \(.*\) .*$/s//\1/p' $root/mnt/ALL.want | \ - sort >$root/mnt/DIVERT.want -sed -n '/^\(DIVERT\|LINK\) /s///p' $root/mnt/ALL.want | \ - sort >$root/mnt/LINK.want - -## Make a list, `DIVERT.have', of paths which already have diversions, and a -## list `LINK.have' of symbolic links into the cross-tools trees. The -## layouts of these files match the `.want' files we just made. -schroot -uroot -rc$sess -- sh -ec ' - dpkg-divert --list | - sed -n "/^diversion of \(.*\) to .* by install-cross-tools\$/s//\1/p" | \ - sort >/mnt/DIVERT.have - { find / -xdev -lname "/usr/local.schroot/cross/*" -printf "%p %l\n" - while read s _; do - if ! [ -L "$s" ]; then continue; fi - t=$(readlink $s) - case $t in /usr/local.schroot/cross/*) continue ;; esac - echo "$s $t" - done /dev/null - } | sort >/mnt/LINK.have' - -## Add diversions for the paths which need one, but don't have one. There's -## a hack here because the `--no-rename' option was required in the same -## version in which is was introduced, so there's no single incantation that -## will work across the boundary. -schroot -uroot -rc$sess -- sh -ec ' - a=$1 - - if dpkg-divert >/dev/null 2>&1 --no-rename --help - then no_rename=--no-rename - else no_rename= - fi - - comm -13 /mnt/DIVERT.have /mnt/DIVERT.want | while read i; do - dpkg-divert --package "install-cross-tools" $no_rename \ - --divert "$i.$a" --add "$i" - done' - $a - -## Go through each diverted tool, and, if it hasn't been moved aside, then -## /link/ it across now. If we rename it, then the chroot will stop working -## -- which is why we didn't allow `dpkg-divert' to do the rename. We can -## tell a tool that hasn't been moved, because it's a symlink into one of the -## cross trees. -while read i; do - if [ -e $root$i ] && ! [ -e $root$i.$a ]; then - if [ -L $root$i ]; then - t=$(readlink $root$i) - case $t in - $crossdir/* | $qemudir/* | /usr/local.schroot/qemu/*) continue ;; - esac - if [ -L $crossdir$i ]; then - u=$(readlink $crossdir$i) - case $t in "$u") continue ;; esac - fi - fi - echo >&2 "$0: preserve old $i" - ln $root$i $root$i.$a - fi -done <$root/mnt/DIVERT.want - -## Update all of the symbolic links which are currently wrong: add links -## which are missing, delete ones which are obsolete, and update ones which -## have the wrong target. -join -j1 -a1 -a2 -e- -o"0 1.2 2.2" \ - $root/mnt/LINK.have $root/mnt/LINK.want | - while read s t0 t1; do - case $t1 in - "$t0") - continue - ;; - -) - echo >&2 "$0: remove obsolete link $s -> $t0" - rm -f $root$s - ;; - *) - case $s in */*) mkdir -p $root${s%/*} ;; esac - rm -f $root$s.new - ln -s $t1 $root$s.new - echo >&2 "$0: link $s -> $t1" - mv -T $root$s.new $root$s - ;; - esac - done - -## Remove diversions from paths which don't need them any more. Here it's -## safe to rename, because either the tool isn't there, in which case it -## obviously wasn't important, or it is, and `dpkg-divert' will atomically -## replace our link with the foreign version. -schroot -uroot -rc$sess -- sh -ec ' - a=$1 - comm -23 /mnt/DIVERT.have /mnt/DIVERT.want | while read i; do - dpkg-divert --package "install-cross-tools" --rename \ - --divert "$i.$a" --remove "$i" - done' - $a - -## Close the session. -schroot -ec$sess - -###----- That's all, folks -------------------------------------------------- diff --git a/bin/mkbuildchroot b/bin/mkbuildchroot deleted file mode 100755 index a6ac135..0000000 --- a/bin/mkbuildchroot +++ /dev/null @@ -1,178 +0,0 @@ -#! /bin/sh -e -### -### Construct a fresh build-chroot base -### -### (c) 2018 Mark Wooding -### - -###----- Licensing notice --------------------------------------------------- -### -### This file is part of the distorted.org.uk chroot maintenance tools. -### -### distorted-chroot is free software: you can redistribute it and/or -### modify it under the terms of the GNU General Public License as -### published by the Free Software Foundation; either version 2 of the -### License, or (at your option) any later version. -### -### distorted-chroot is distributed in the hope that it will be useful, -### but WITHOUT ANY WARRANTY; without even the implied warranty of -### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -### General Public License for more details. -### -### You should have received a copy of the GNU General Public License -### along with distorted-chroot. If not, write to the Free Software -### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -### USA. - -. state/config.sh # @@@config@@@ - -## Convert the PROXY configuration setting into something that will affect -## `debootstrap'. -case $PROXY in nil) ;; *) http_proxy=$PROXY; export PROXY ;; esac - -## Parse the command-line. -badp=nil forcep=nil -while getopts "f" opt; do - case $opt in - f) forcep=t ;; - *) badp=t ;; - esac -done -shift $(( $OPTIND - 1 )) -case $# in 2) ;; *) badp=t ;; esac -case $badp in t) echo >&2 "usage: $0 [-f] DIST ARCH"; exit 2 ;; esac -d=$1 a=$2 - -case $d-$a in *-*-*) echo >&2 "$0: bad chroot name \`$arg'"; exit 2 ;; esac -if [ ! -d /dev/$VG/ ]; then echo >&2 "$0: no volume group \`$VG'"; exit 2; fi - -## Decide whether we need to do special things for installing a foreign -## architecture. -qemup=nil dbsopts= -for fa in $FOREIGN_ARCHS; do - case $fa in - "$a") - qemup=t dbsopts=--foreign - eval qarch=\$${a}_QEMUARCH qhost=\$${a}_QEMUHOST - break - ;; - esac -done - -## Construct the logical volume and lay a filesystem onto it. -lv=$LVPREFIX$d-$a -mnt=$HERE/mnt/$lv -mkdir -p $mnt -if mountpoint -q $mnt; then umount $mnt; fi -if [ -b /dev/$VG/$lv ]; then - case $forcep in - nil) echo >&2 "$0: volume \`$lv' already exists"; exit 2 ;; - t) lvremove -f $VG/$lv ;; - esac -fi -lvcreate --yes $LVSZ -n$lv $VG -mkfs -j -L$d-$a /dev/$VG/$lv -mount -orelatime,data=writeback,commit=3600,barrier=0 /dev/$VG/$lv $mnt/ -mkdir -m755 $mnt/fs/ -chmod 750 $mnt/ - -## Install the base system. -want=$BASE_PACKAGES -pkgs=; for p in $want; do pkgs=${pkgs:+$pkgs,}$p; done -eatmydata debootstrap $dbsopts --arch=$a --variant=minbase \ - --include=$pkgs $d $mnt/fs/ $DEBMIRROR - -## If this is a cross-installation, then install the necessary `qemu' and -## complete the installation. -case $qemup in - t) - install $LOCAL/cross/$d-$qhost/QEMU/qemu-$qarch-static \ - $mnt/fs/usr/bin/ - chroot $mnt/fs/ /debootstrap/debootstrap --second-stage - ln -sf /usr/local.schroot/cross/$d-$qhost/QEMU/qemu-$qarch-static \ - $mnt/fs/usr/bin/ - ;; -esac - -## Set up `/usr/local'. -rm -rf $mnt/fs/usr/local/; ln -s local.schroot/$a $mnt/fs/usr/local - -## Install the `apt' configuration. -rm -rf $mnt/fs/etc/apt/apt.conf $mnt/fs/etc/apt/sources.list -for c in $LOCAL/etc/apt/apt.conf.d/*; do - ln -s /usr/local.schroot/${c#$LOCAL/} $mnt/fs/etc/apt/apt.conf.d/ -done -ln -s /usr/local.schroot/etc/apt/sources.$d $mnt/fs/etc/apt/sources.list - -cat >$mnt/fs/etc/apt/apt.conf.d/20arch <$mnt/fs/usr/sbin/policy-rc.d <&2 "policy-rc.d: Services disabled by policy." -exit 101 -EOF -chmod +x $mnt/fs/usr/sbin/policy-rc.d - -## Hack the dynamic linker to prefer libraries in `/usr' over `/usr/local'. -cat >$mnt/fs/etc/ld.so.conf.d/libc.conf <$mnt/fs/etc/ld.so.conf.d/zzz-local.conf </dev/null 2>&1 --no-rename --help - then no_rename=--no-rename - else no_rename= - fi - - dpkg-divert --package install-cross-tools \$no_rename \ - --divert /usr/bin/qemu-$qarch-static.$a --add /usr/bin/qemu-$qarch-static" - - ## Install faster native tools. - $STATE/bin/install-cross-tools $d $a -esac - -## Install extra packages now that everything should go fairly quickly. -want=$EXTRA_PACKAGES -pkgs=; for p in $want; do pkgs=${pkgs:+$pkgs,}$p; done -schroot -uroot -csource:$lv -- eatmydata apt-get -y install $pkgs - -## Set the chroot's package state up properly. -schroot -uroot -csource:$lv -- eatmydata sh -e -c ' - apt-get update - apt-get -y upgrade - locale-gen - ldconfig - apt-get -y autoremove - apt-get clean' - -###----- That's all, folks -------------------------------------------------- diff --git a/bin/update-cross-tools b/bin/update-cross-tools deleted file mode 100755 index a287be3..0000000 --- a/bin/update-cross-tools +++ /dev/null @@ -1,277 +0,0 @@ -#! /bin/sh -e -### -### Fetch native versions of tools for insertion into foreign chroots -### -### (c) 2018 Mark Wooding -### - -###----- Licensing notice --------------------------------------------------- -### -### This file is part of the distorted.org.uk chroot maintenance tools. -### -### distorted-chroot is free software: you can redistribute it and/or -### modify it under the terms of the GNU General Public License as -### published by the Free Software Foundation; either version 2 of the -### License, or (at your option) any later version. -### -### distorted-chroot is distributed in the hope that it will be useful, -### but WITHOUT ANY WARRANTY; without even the implied warranty of -### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -### General Public License for more details. -### -### You should have received a copy of the GNU General Public License -### along with distorted-chroot. If not, write to the Free Software -### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -### USA. - -. state/config.sh # @@@config@@@ - -###-------------------------------------------------------------------------- -### Utilities. - -chase_link () { - p=$1 d= - ## Copy an absolute path P from the donor tree `$root/' into the - ## cross-tools tree `$crossnew/'. If resolving P involves traversing a - ## symbolic link, then ensure that the pieces of filesystem it directs us - ## to are also copied. - - ## Work through the remaining components of the path. - while :; do - - ## Analyse the first remaining component of the path P. - case $p in - - ## It's empty. We're done. - "") break ;; - - ## A redundant `/' or `./'. Skip it. - "/"*) p=${p#/} ;; - "./"*) p=${p#./} ;; - - ## A `../'. Strip off the trailing component of D. - "../"*) - p=${p#../} - case $d in */*) d=${d%/*} ;; *) d= ;; esac - ;; - - ## Something else. Transfer the component name to D. - *) - case $p in */*) f=${p%%/*} p=${p#*/} ;; *) f=$p p="" ;; esac - d=${d:+$d/}$f - ;; - esac - - ## If D doesn't refer to a file in the cross-tools tree, then maybe it - ## refers to something in the donor tree. Find out what, and copy it - ## into the cross-tools tree. - if ! [ -e "$crossnew$d" ] && ! [ -L "$crossnew$d" ]; then - if [ -d "$root/$d" ] && ! [ -L "$root/$d" ]; then - mkdir "$crossnew$d" - else - echo >&2 "$0: copy /$d to satisfy symlinks" - rsync -aHR $root/./$d $crossnew - fi - fi - - ## If D refers to a symbolic link, then append the link target to P, so - ## that we can make sure we copy the target. - if [ -L "$crossnew$d" ]; then - t=$(readlink "$crossnew$d") - case $t in /*) t=${t#/} d= ;; esac - case $d in */*) d=${d%/*} ;; *) d= ;; esac - p=$t${p:+/$p} - fi - done -} - -###-------------------------------------------------------------------------- -### Main program. - -## Parse the command line. -badp=nil -case $# in 2) ;; *) badp=t ;; esac -case $badp in t) echo >&2 "usage: $0 DIST MYARCH"; exit 2 ;; esac -d=$1 myarch=$2 - -## Keep track of our original stdout. -exec 3>&1 - -## Figure out derived architecture names. -mymulti=$(dpkg-architecture -a$myarch -qDEB_HOST_MULTIARCH) - -## First, set `cross_archs' as a list of GNUish names for our supported -## foreign architectures. -cross_archs="arm-linux-gnueabi arm-linux-gnueabihf aarch64-linux-gnu" - -## Make a list of extra packages we'll need to install to obtain our tools. -cross_pkgs=" - apt bash ccache coreutils dash eatmydata fakeroot findutils - gpgv gzip m4 make mawk qemu-user-static sed tar xz-utils" -for a in $cross_archs; do - for i in gcc g++ binutils; do - cross_pkgs="$cross_pkgs $i-$a" - done -done -cross_pkgs=$(echo $cross_pkgs) - -## Make an enormous shopping list of paths. -## -## The `wanted' list consists of two kinds of items: an absolute path names a -## prefix (not necessarily a directory name) to be attached to the following -## relative names, up to the end of the list or the next absolute path. -wanted=" - /usr/bin/ apt apt-cache apt-config apt-get apt-key apt-mark - /usr/lib/apt/ methods/ solvers/ - - /bin/ cat chgrp chown cp date dd df dir echo false ln ls mkdir - mknod mktemp mv pwd readlink rm rmdir sleep stty sync touch - true uname vdir - /usr/bin/ [ arch b2sum base32 base64 basename chcon cksum comm - csplit cut dircolors dirname du env expand expr factor fmt - fold groups head hostid id install join link logname md5sum - mkfifo nice nl nohup nproc numfmt od paste pathchk pinky pr - printenv printf ptx realpath runcon seq sha1sum sha224sum - sha256sum sha384sum sha512sum shred shuf sort split stat - stdbuf sum tac tail tee test timeout tr truncate tsort tty - unexpand uniq unlink users wc who whoami yes - /usr/lib/$mymulti/ coreutils/ - - /lib/$mymulti/ libnss_*.so.* - - /usr/bin/ gpgv - - /usr/bin/ qemu-*-static - - /bin/ bash dash gzip sed tar - /usr/bin/ ccache find m4 make mawk xargs xz - /usr/lib/$mymulti/ libeatmydata.so* libfakeroot/ - - /etc/ld.so.conf.d/ $mymulti.conf fakeroot*.conf" - -for a in $cross_archs; do - wanted="$wanted - - /usr/bin/$a- addr2line ar as c++filt dwp elfedit gprof ld ld.* - nm objcopy objdump ranlib readelf size strings strip - - /usr/bin/$a- cpp gcc g++ gcov gcov-dump gcov-tool gprof - gcc-ar gcc-nm gcc-ranlib - /usr/lib/gcc-cross/$a/ ..." -done -wanted=$(echo $wanted) - -## Figure out how to recognize dynamic executables. -case $myarch in - i386) elfsig=7f454c46010101??0000000000000000????0300 ;; - amd64) elfsig=7f454c46020101??0000000000000000????3e00 ;; - *) echo >&2 "$0: unsupported local arch \`$myarch'"; exit 2 ;; -esac - -## Open a session to the donor chroot. -echo >&2 "$0: create $d snapshot" -sess=$(schroot -bc$LVPREFIX$d-$myarch 3>&-) - -## Make sure the donor tree is up-to-date, and install the extra packages we -## need. -schroot -uroot -rc$sess -- eatmydata sh -ec " - apt-get update - apt-get -y upgrade - apt-get -y install $cross_pkgs" - -## Establish some pathnames. Prepare a place for our cross-tools tree. -crossdir=$LOCAL/cross/$d-$myarch/ -crossold=${crossdir%/}.old/ crossnew=${crossdir%/}.new/ -root=/schroot/$sess/fs -rm -rf $crossnew; mkdir -p $crossnew - -## Work through the shopping list, copying the things it names into the -## cross-tools tree. -dir=/ -for i in $wanted; do - case $i in - /*) - dir=$i - ;; - *) - case $i in ...) f=$dir ;; *) f=$dir$i ;; esac - echo >&2 "$0: copy $f" - rsync -aHR $root/.$f $crossnew - ;; - esac -done - -## Chase links in the new tree, copying extra stuff that we'll need. -find $crossnew -xtype l -print | while read i; do - chase_link ${i#$crossnew} -done - -## Search the new tree for ELF binaries, and build a list of them in -## `QUEUE.in'. -find $crossnew -type f -print | while read i; do - sig=$(head -c20 "$i" | bincode -e -m0 -flowerc hex) - case $sig in $elfsig) echo "$i" ;; esac -done >$root/private/QUEUE.in - -while [ -s $root/private/QUEUE.in ]; do - ## Work through the ELF binaries in `QUEUE.in', determining which shared - ## libraries they'll need. Write the list of dependencies to `QUEUE.out' - schroot -uroot -rc$sess -- eatmydata sh -ec ' - prog=$1 - while read i; do - echo >&2 "$prog: scanning binary $i" - ldd "$i" | while read a b c d; do - case $a:$b:$c:$d in - not:a:dynamic:executable) ;; - statically:linked::) ;; - /*) echo "$a" ;; - *:=\>:/*) echo "$c" ;; - linux-*) ;; - *) echo >&2 "$i: unable to find $a"; exit 2 ;; - esac - done - done /private/QUEUE.out' - "$0" - - ## Work through the shared libraries in `QUEUE.out', copying them to the - ## cross-tools tree if they're not there already. Add the new ones to a - ## new `QUEUE.in' file to scan them in turn. - while read i; do - if [ -e "$crossnew$i" ] || [ -L "$crossnew$i" ] - then continue; fi - if [ -d "$root$i" ]; then continue; fi - echo >&2 "$0: copy $i" - rsync -aHR $root/.$i $crossnew >&3 - chase_link $i >&3 - sig=$(head -c20 $crossnew$i | bincode -e -m0 -flowerc hex) - case $sig in $elfsig) echo "$i" ;; esac - done <$root/private/QUEUE.out >$root/private/QUEUE.in -done - -## Set up the cross-compiler. This is rather hairy. -echo >&2 "$0: establish TOOLCHAIN" -for a in $cross_archs; do - tooldir=$crossnew/TOOLCHAIN/$a - mkdir -p $tooldir - for i in $crossnew/usr/bin/$a-*; do - t=${i#$crossnew/usr/bin/} - mv $i $tooldir/$t - ln -s $t $tooldir/${t#$a-} - done -done -mkdir $crossnew/TOOLCHAIN/lib -ln -s ../../usr/lib/gcc-cross $crossnew/TOOLCHAIN/lib/ - -## Set up the emulator. -echo >&2 "$0: establish QEMU" -mkdir $crossnew/QEMU -mv $crossnew/usr/bin/qemu-*-static $crossnew/QEMU/ - -## We're done. Remove the snapshot, and replace the old cross-tools tree -## with our new one. -echo >&2 "$0: remove snapshot" -schroot -ec$sess 3>&- -if [ -d $crossdir ]; then mv $crossdir $crossold; fi -mv $crossnew $crossdir; rm -rf $crossold -echo >&2 "$0: committed $crossdir" - -###----- That's all, folkd --------------------------------------------------