| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- #!/bin/sh
- ##
- ## openpkg.boot -- OpenPKG bootstrap procedure (look Ma, without hands ;)
- ## Copyright (c) 2000-2002 Cable & Wireless Deutschland GmbH
- ## Copyright (c) 2000-2002 The OpenPKG Project <http://www.openpkg.org/>
- ## Copyright (c) 2000-2002 Ralf S. Engelschall <rse@engelschall.com>
- ##
- # This is a very tricky procedure for building the OpenPKG bootstrap
- # package via the RPM specification openpkg.spec, but without
- # requiring that OpenPKG's RPM already exists. For this the
- # openpkg.spec file is manually executed here in order to build
- # OpenPKG RPM the first time (that is, we emulate a sufficient
- # subset of the RPM functionality), followed by a second round over
- # openpkg.spec with the real (and then existing) OpenPKG RPM tool.
- # Also keep in mind that lots of tricks are played here in order to
- # perform all the steps without having to touch the real installation
- # location. That is the whole procedure can (and should) be performed
- # by a non-priviledged user and no access to the real installation
- # location filesystem location.
- me="openpkg.boot"
- ##
- ## command line handling
- ##
- # command line parameters (defaults)
- help=0
- verbose=''
- prefix=''
- usr=''; grp=''
- susr=''; sgrp=''
- musr=''; mgrp=''
- rusr=''; rgrp=''
- nusr=''; ngrp=''
- bs=0
- # parse command line options
- for opt
- do
- case $opt in
- -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
- *) arg='' ;;
- esac
- case $opt in
- -h | --help ) help=1 ;;
- -v | --verbose ) verbose=v ;;
- --prefix=* ) prefix=$arg ;;
- --usr=* | --user=* ) usr=$arg ;;
- --grp=* | --group=* ) grp=$arg ;;
- --susr=* ) susr=$arg ;;
- --sgrp=* ) sgrp=$arg ;;
- --musr=* ) musr=$arg ;;
- --mgrp=* ) mgrp=$arg ;;
- --rusr=* ) rusr=$arg ;;
- --rgrp=* ) rgrp=$arg ;;
- --nusr=* ) nusr=$arg ;;
- --ngrp=* ) ngrp=$arg ;;
- -bs | -s ) bs=1 ;;
- * ) help=1 ;;
- esac
- done
- if [ ".$bs" = .0 -a ".$prefix" = . ]; then
- help=1
- fi
- if [ ".$help" = .1 ]; then
- echo "Usage: sh $me [-h|--help] [-v|--verbose]" 2>&1
- echo " --prefix=<prefix> [--user=<usr>] [--group=<grp>]" 2>&1
- echo " [--{s,m,r,n}usr=<usr>] [--{s,m,r,n}grp=<grp>]" 2>&1
- exit 1
- fi
- # determine missing parameters
- eval `sh aux.usrgrp.sh \
- --usr="$usr" --grp="$grp" \
- --susr="$susr" --sgrp="$sgrp" \
- --musr="$musr" --mgrp="$mgrp" \
- --rusr="$rusr" --rgrp="$rgrp" \
- --nusr="$nusr" --ngrp="$ngrp"`
- ##
- ## determine package information
- ##
- name="openpkg"
- spec="$name.spec"
- version=`grep V_openpkg $spec | head -1 | awk '{ printf("%s", $3); }'`
- release=`grep R_openpkg $spec | head -1 | awk '{ printf("%s", $3); }'`
- ##
- ## display headline
- ##
- sh ./shtool echo -e "%BOpenPKG Bootstrap Procedure%b"
- echo "++ bootstrap version: $version-$release"
- echo "++ user/group pairs: $susr/$sgrp $musr/$mgrp $rusr/$rgrp $nusr/$ngrp"
- ##
- ## optionally roll just a bootstrap source package
- ##
- if [ ".$bs" = .1 ]; then
- srcdir=.
- if [ -d ../../DST ]; then
- dstdir=../../DST/openpkg
- else
- dstdir=.
- fi
- tmpdir="/tmp/$me.$$"
- if [ -d ../PKG/SRC ]; then
- pkgdir=../PKG/SRC
- elif [ -d ../PKG ]; then
- pkgdir=../PKG
- elif [ -d ../../PKG/SRC ]; then
- pkgdir=../../PKG/SRC
- elif [ -d ../../PKG ]; then
- pkgdir=../../PKG
- else
- pkgdir=..
- fi
- echo "** rolling source bootstrap package:"
- echo " $pkgdir/$name-$version-$release.src.sh"
- rm -rf $tmpdir
- mkdir $tmpdir
- (cd $dstdir && tar cf - *) | (cd $tmpdir && tar xf -)
- (cd $srcdir && tar cf - *) | (cd $tmpdir && tar xf -)
- sed <$srcdir/aux.wrapsrc.sh >$pkgdir/$name-$version-$release.src.sh \
- -e "s;@DIR@;$name-$version-$release.src;" -e "s;@TGZ@;$name-$version-$release.src.tar.Z;"
- (cd $tmpdir && tar cf - *) | compress |\
- uuencode $name-$version-$release.src.tar.Z \
- | dd bs=64000 2>/dev/null >>$pkgdir/$name-$version-$release.src.sh
- exit 0
- fi
- ##
- ## calculate location id
- ##
- prefix=`echo "$prefix" | sed -e 's;//*;/;g' -e 's;/$;;'`
- if [ ".`expr $prefix : '/[^/][^/]*$'`" != .0 ]; then
- loc=`echo $prefix | cut -c2-4`
- else
- loc=`echo $prefix | sed -e 's;/\(.\)[^/]*;\1;g' | cut -c1-3`
- fi
- echo "++ location id: $loc"
- ##
- ## determine distribution directory
- ##
- V_rpm=`grep V_rpm $spec | head -1 | awk '{ printf("%s", $3); }'`
- if [ -f "../../DST/openpkg/rpm-${V_rpm}.tar.gz" ]; then
- distdir="`cd ../../DST/openpkg; pwd`" # developer only
- else
- distdir="`pwd`"
- fi
- echo "++ distribution directory: $distdir"
- ##
- ## perform prerequisite checks
- ##
- sh ./aux.prereq.sh source
- ##
- ## find reasonable run-time paths and tools
- ##
- # find reasonable temporary directory
- tmpdir="/tmp"
- test ".$TMPDIR" != . && tmpdir="$TMPDIR"
- test ".$TEMPDIR" != . && tmpdir="$TEMPDIR"
- # find reasonable safe program path
- test ".$PATH" = . && PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin"
- for dir in /usr/ccs/bin /usr/xpg4/bin; do
- test -d $dir && PATH="$PATH:$dir"
- done
- export PATH
- # find reasonable TAR
- l_tar=''
- for t in gtar tar; do
- for p in `IFS=":"; echo . $PATH`; do
- if [ -f "$p/$t" ]; then
- l_tar="$p/$t"
- break
- fi
- done
- [ ".$l_tar" != . ] && break
- done
- if [ ".$l_tar" = . ]; then
- echo "$0:FAILED: required TAR not found"
- exit 1
- fi
- # find required Make tool
- l_make=''
- for t in gmake make; do
- for p in `IFS=":"; echo . $PATH`; do
- if [ -f "$p/$t" ]; then
- l_make="$p/$t"
- break
- fi
- done
- [ ".$l_make" != . ] && break
- done
- if [ ".$l_make" = . ]; then
- echo "$0:FAILED: required Make tool not found"
- exit 1
- fi
- # find required [GNU] C Compiler
- l_cc=''
- for t in egcc ggcc gcc cc; do
- for p in `IFS=":"; echo . $PATH`; do
- if [ -f "$p/$t" ]; then
- # if [ ".`$p/$t --version 2>/dev/null | grep '[23]\.[789]'`" != . ]; then
- l_cc="$p/$t"
- break
- # fi
- fi
- done
- [ ".$l_cc" != . ] && break
- done
- if [ ".$l_cc" = . ]; then
- echo "$0:FAILED: required [GNU] C/C++ compiler not found"
- exit 1
- fi
- ##
- ## execute the spec file manually by emulating
- ## the behaviour of the OpenPKG RPM tool.
- ##
- # create script prolog
- prolog="$tmpdir/openpkg.boot.prolog.sh"
- cp /dev/null $prolog
- (
- echo "_specdir=`pwd`"
- echo "_sourcedir=$distdir"
- echo "_tmppath=$tmpdir"
- echo "_builddir=$tmpdir"
- echo "l_prefix=$prefix"
- echo "l_location=$loc"
- echo "l_buildroot=$tmpdir/$name-$version-root"
- echo "l_susr=$susr"
- echo "l_sgrp=$sgrp"
- echo "l_musr=$musr"
- echo "l_mgrp=$mgrp"
- echo "l_rusr=$rusr"
- echo "l_rgrp=$rgrp"
- echo "l_nusr=$nusr"
- echo "l_ngrp=$ngrp"
- echo "l_tar=$l_tar"
- echo "l_make=$l_make"
- echo "l_cc=$l_cc"
- grep '%define' $spec | \
- sed \
- -e 's:^%define *\([^ ]*\) *\(.*\):\1="\2":'
- grep "^[A-Za-z0-9]*: *" $spec | \
- sed \
- -e 's;^\([A-Za-z0-9]*\): *\(.*\)$;\1="\2";' \
- -e 's;^A;a;' -e 's;^B;b;' -e 's;^C;c;' -e 's;^D;d;' -e 's;^E;e;' \
- -e 's;^F;f;' -e 's;^G;g;' -e 's;^H;h;' -e 's;^I;i;' -e 's;^J;j;' \
- -e 's;^K;k;' -e 's;^L;l;' -e 's;^M;m;' -e 's;^N;n;' -e 's;^O;o;' \
- -e 's;^P;p;' -e 's;^Q;q;' -e 's;^R;r;' -e 's;^S;s;' -e 's;^T;t;' \
- -e 's;^U;u;' -e 's;^V;v;' -e 's;^W;w;' -e 's;^X;x;' -e 's;^Y;y;' \
- -e 's;^Z;z;' -e 's;^buildRoot;buildroot;'
- echo "RPM_BUILD_ROOT=\"%{buildroot}\""
- echo "RPM_BUILD_DIR=\"%{_builddir}\""
- echo "RPM_SOURCE_DIR=\"$distdir\""
- echo "export RPM_BUILD_ROOT"
- echo "export RPM_BUILD_DIR"
- echo "export RPM_SOURCE_DIR"
- echo "set -x"
- echo "umask 022"
- echo "cd \$RPM_BUILD_DIR"
- ) | sed -e 's;%{\([^}]*\)};${\1};g' >$prolog
- # install package via RPM spec file by faking a
- # sufficiently enough RPM run-time environment
- runscript () {
- step=$1
- script="$tmpdir/openpkg.boot.$step.sh"
- echo ". $prolog" >$script
- sed -e "/^%$step/,/^%/ p" -e 'd' <$spec | \
- sed -e '/^%/d' | \
- sed -e 's;%{SOURCE \([^ ]*\.tar[^ ]*\)};${RPM_DIST_DIR}/\1;g' \
- -e 's;%{SOURCE \([^ ]*\)};${RPM_SOURCE_DIR}/\1;g' | \
- sed -e 's;%{[?]\([^:]*\):\([^}]*\)};${\1+\2};g' \
- -e 's;%{![?]\([^:]*\):\([^}]*\)};${\1-\2};g' \
- -e 's;%{\([^}]*\)};${\1};g' >>$script
- echo "++ executing(%$step): sh $script"
- sh $script
- if [ $? -ne 0 ]; then
- rm -f $script
- echo "$0:ERROR: script returned non-null value"
- exit 1
- fi
- rm -f $script
- }
- runscript prep
- runscript build
- runscript install
- ##
- ## adjust build environment so that the installed
- ## "rpm" is actually useable, although it still resides in
- ## the temporary location instead of the real location.
- ##
- # suck in prolog in order to get variables from the spec file
- cwd=`pwd`
- . $prolog
- cd $cwd
- # suck in buildenv script in order to get musr/mgrp
- . $tmpdir/openpkg-*/.buildenv
- # create a custom "rpm" command
- echo "++ creating custom RPM command"
- rm -f $tmpdir/rpm >/dev/null 2>&1
- rmdir $tmpdir/rpm >/dev/null 2>&1
- if [ -d "$tmpdir/rpm" ]; then
- echo "$0:ERROR: directory $tmpdir/rpm exists, cannot create file with same name"
- exit 1
- fi
- if [ -f "$tmpdir/rpm" ]; then
- echo "$0:ERROR: file $tmpdir/rpm exists, cannot override"
- exit 1
- fi
- echo "#!/bin/sh" >$tmpdir/rpm
- echo "exec $RPM_BUILD_ROOT$prefix/lib/openpkg/rpm --rcfile $tmpdir/rpm.1 \"\$@\"" >>$tmpdir/rpm
- chmod a+x $tmpdir/rpm
- # direct our own "rpm" tool to adjusted macro sets
- sed <`SOURCE rpmrc` >$tmpdir/rpm.1 \
- -e "s;^\\(macrofiles:\\) .*;\\1 $tmpdir/rpm.2:$tmpdir/rpm.3;"
- # use an adjusted vendor macro set
- sed <$RPM_BUILD_ROOT$prefix/lib/openpkg/macros >$tmpdir/rpm.2 \
- -e "s;$prefix;$RPM_BUILD_ROOT$prefix;g"
- # override the vendor macro set
- sed <`SOURCE rpmmacros` >$tmpdir/rpm.3 \
- -e "s;@SUSR@;$susr;" \
- -e "s;@SGRP@;$sgrp;" \
- -e "s;@MUSR@;$musr;" \
- -e "s;@MGRP@;$mgrp;" \
- -e "s;@RUSR@;$rusr;" \
- -e "s;@RGRP@;$rgrp;" \
- -e "s;@NUSR@;$nusr;" \
- -e "s;@NGRP@;$ngrp;" \
- -e "s;@LOC@;$loc;" \
- -e "s;^\\(%l_root_install *\\)@l_prefix@;\\1 $prefix;" \
- -e "s;^\\(%l_root_rpm *\\)@l_prefix@;\\1 $RPM_BUILD_ROOT$prefix;" \
- -e "s;^\\(%_specdir *\\).*;\\1 `pwd`;" \
- -e "s;^\\(%_sourcedir *\\).*;\\1 $distdir;" \
- -e "s;^\\(%_builddir *\\).*;\\1 $tmpdir;" \
- -e "s;^\\(%_tmppath *\\).*;\\1 $tmpdir;" \
- -e "s;^\\(%_buildshell *\\).*;\\1 /bin/sh;"
- # use an own $HOME/.popt in order to make sure the "rpm"
- # tool is able to execute its sub-tools "rpm<x>".
- V_rpm=`grep V_rpm $spec | head -1 | awk '{ printf("%s", $3); }'`
- sed <$RPM_BUILD_ROOT$prefix/lib/openpkg/rpmpopt-${V_rpm} >$tmpdir/.popt \
- -e "s;^\\(rpm.*exec.*\\)\\(rpm[bdeukv]*\\);\\1$RPM_BUILD_ROOT$prefix/lib/openpkg/\\2;"
- # activate the .popt file
- HOME=$tmpdir
- export HOME
- ##
- ## now initialize the RPM database under the temporary install location
- ##
- echo "++ initializing RPM database"
- $tmpdir/rpm --initdb
- ##
- ## now turn over and re-iterate over the RPM spec, but this time
- ## with the real RPM tool.
- ##
- echo "++ re-iterating over RPM specification procedures"
- OPENPKG_BOOT=1
- export OPENPKG_BOOT
- $tmpdir/rpm -bb $spec
- ##
- ## and finally overwrite the installation again, but this time by
- ## installing officially through the "rpm" tool. This way we achieve
- ## that RPM is remembered as an RPM package in its own database. We
- ## just have to make sure the package is relocated while installing.
- ## For this we could use --prefix=$RPM_BUILD_ROOT$prefix, but this
- ## would create an incorrect filelist for "rpm" in the database.
- ## Instead we use the --justdb option which means "rpm" behaves as it
- ## would install into the real location, but does not actually install
- ## anything. But as a side-effect, the database is now correct.
- ##
- echo "++ overwriting RPM installation by installing via RPM itself"
- $tmpdir/rpm -Uvh --force --noscripts --justdb --ignoresize \
- $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-*.rpm
- ## Puhhhh!!! what a tricky bootstrapping procedure. But now we are
- ## mostly finished. All we finally have to do is to roll a bootstrap
- ## tarball in addition to the binary RPM and save the stuff in a
- ## permanent location.
- v="$version-$release"
- t="`$tmpdir/rpm --eval '%{_target}'`-$loc"
- # find a reasonable destination directory for packages
- if [ -d ../PKG/BIN ]; then
- dstdir=../PKG/BIN
- elif [ -d ../PKG ]; then
- dstdir=../PKG
- elif [ -d ../../PKG/BIN ]; then
- dstdir=../../PKG/BIN
- elif [ -d ../../PKG ]; then
- dstdir=../../PKG
- else
- dstdir=..
- fi
- # create Source-RPM file
- echo "++ creating bootstrap source RPM file"
- $tmpdir/rpm -bs --nodeps $spec
- cp $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.src.rpm $dstdir/
- rm -f $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.src.rpm
- # create Binary-RPM file
- echo "++ creating bootstrap binary RPM file"
- cp $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.$t.rpm $dstdir/
- rm -f $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.$t.rpm
- # create Binary-Bootstrap file
- echo "++ creating bootstrap binary shell script"
- cat $spec | sed -e "/^%pre$/,/^%/ p" -e 'd' | sed -e '/^%/d' -e 's/^ //' >$tmpdir/rpm.pre
- sed <`SOURCE aux.wrapbin.sh` \
- -e "s;@SUSR@;$susr;" -e "s;@SGRP@;$sgrp;" \
- -e "s;@MUSR@;$musr;" -e "s;@MGRP@;$mgrp;" \
- -e "s;@RUSR@;$rusr;" -e "s;@RGRP@;$rgrp;" \
- -e "s;@NUSR@;$nusr;" -e "s;@NGRP@;$ngrp;" \
- -e "s;@l_prefix@;$prefix;" -e "s;@TGZ@;openpkg-$v.$t.tar.Z;" \
- -e "/^@PRE@/r $tmpdir/rpm.pre" |\
- sed -e '/^@PRE@/d' >$dstdir/openpkg-$v.$t.sh
- files=`cat $spec |\
- sed -e '1,/%files/d' -e '/%clean/,$d' |\
- grep -v '^ *$' | grep -v '%defattr' |\
- sed -e 's;%config *;;' -e 's;%dir *;;' -e 's;%{l_prefix}/;;' -e 's;^ *;;' -e "s;%{V_rpm};${V_rpm};"`
- ( cd $RPM_BUILD_ROOT$prefix;
- $RPM_BUILD_ROOT$prefix/lib/openpkg/tar --no-recursion -cf - $files) |\
- compress | uuencode openpkg-$v.$t.tar.Z >>$dstdir/openpkg-$v.$t.sh
- # cleanup
- echo "++ cleaning up"
- rm -rf $RPM_BUILD_ROOT
- rm -rf $tmpdir/$name-$version
- rm -f $tmpdir/rpm $tmpdir/rpm.[123] $tmpdir/.popt $tmpdir/rpm.pre
- rm -f $prolog
- # final hint about results
- set +x
- echo "++ resulting files (placed into $dstdir):"
- (cd $dstdir; ls -l openpkg-$v.$t.sh openpkg-$v.$t.rpm openpkg-$v.src.rpm)
|