openpkg.boot 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. #!/bin/sh
  2. ##
  3. ## openpkg.boot -- OpenPKG bootstrap procedure (look Ma, without hands ;)
  4. ## Copyright (c) 2000-2002 Cable & Wireless Deutschland GmbH
  5. ## Copyright (c) 2000-2002 The OpenPKG Project <http://www.openpkg.org/>
  6. ## Copyright (c) 2000-2002 Ralf S. Engelschall <rse@engelschall.com>
  7. ##
  8. # This is a very tricky procedure for building the OpenPKG bootstrap
  9. # package via the RPM specification openpkg.spec, but without
  10. # requiring that OpenPKG's RPM already exists. For this the
  11. # openpkg.spec file is manually executed here in order to build
  12. # OpenPKG RPM the first time (that is, we emulate a sufficient
  13. # subset of the RPM functionality), followed by a second round over
  14. # openpkg.spec with the real (and then existing) OpenPKG RPM tool.
  15. # Also keep in mind that lots of tricks are played here in order to
  16. # perform all the steps without having to touch the real installation
  17. # location. That is the whole procedure can (and should) be performed
  18. # by a non-priviledged user and no access to the real installation
  19. # location filesystem location.
  20. me="openpkg.boot"
  21. ##
  22. ## command line handling
  23. ##
  24. # command line parameters (defaults)
  25. help=0
  26. verbose=''
  27. prefix=''
  28. usr=''; grp=''
  29. susr=''; sgrp=''
  30. musr=''; mgrp=''
  31. rusr=''; rgrp=''
  32. nusr=''; ngrp=''
  33. bs=0
  34. # parse command line options
  35. for opt
  36. do
  37. case $opt in
  38. -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
  39. *) arg='' ;;
  40. esac
  41. case $opt in
  42. -h | --help ) help=1 ;;
  43. -v | --verbose ) verbose=v ;;
  44. --prefix=* ) prefix=$arg ;;
  45. --usr=* | --user=* ) usr=$arg ;;
  46. --grp=* | --group=* ) grp=$arg ;;
  47. --susr=* ) susr=$arg ;;
  48. --sgrp=* ) sgrp=$arg ;;
  49. --musr=* ) musr=$arg ;;
  50. --mgrp=* ) mgrp=$arg ;;
  51. --rusr=* ) rusr=$arg ;;
  52. --rgrp=* ) rgrp=$arg ;;
  53. --nusr=* ) nusr=$arg ;;
  54. --ngrp=* ) ngrp=$arg ;;
  55. -bs | -s ) bs=1 ;;
  56. * ) help=1 ;;
  57. esac
  58. done
  59. if [ ".$bs" = .0 -a ".$prefix" = . ]; then
  60. help=1
  61. fi
  62. if [ ".$help" = .1 ]; then
  63. echo "Usage: sh $me [-h|--help] [-v|--verbose]" 2>&1
  64. echo " --prefix=<prefix> [--user=<usr>] [--group=<grp>]" 2>&1
  65. echo " [--{s,m,r,n}usr=<usr>] [--{s,m,r,n}grp=<grp>]" 2>&1
  66. exit 1
  67. fi
  68. # determine missing parameters
  69. eval `sh aux.usrgrp.sh \
  70. --usr="$usr" --grp="$grp" \
  71. --susr="$susr" --sgrp="$sgrp" \
  72. --musr="$musr" --mgrp="$mgrp" \
  73. --rusr="$rusr" --rgrp="$rgrp" \
  74. --nusr="$nusr" --ngrp="$ngrp"`
  75. ##
  76. ## determine package information
  77. ##
  78. name="openpkg"
  79. spec="$name.spec"
  80. version=`grep V_openpkg $spec | head -1 | awk '{ printf("%s", $3); }'`
  81. release=`grep R_openpkg $spec | head -1 | awk '{ printf("%s", $3); }'`
  82. ##
  83. ## display headline
  84. ##
  85. sh ./shtool echo -e "%BOpenPKG Bootstrap Procedure%b"
  86. echo "++ bootstrap version: $version-$release"
  87. echo "++ user/group pairs: $susr/$sgrp $musr/$mgrp $rusr/$rgrp $nusr/$ngrp"
  88. ##
  89. ## optionally roll just a bootstrap source package
  90. ##
  91. if [ ".$bs" = .1 ]; then
  92. srcdir=.
  93. if [ -d ../../DST ]; then
  94. dstdir=../../DST/openpkg
  95. else
  96. dstdir=.
  97. fi
  98. tmpdir="/tmp/$me.$$"
  99. if [ -d ../PKG/SRC ]; then
  100. pkgdir=../PKG/SRC
  101. elif [ -d ../PKG ]; then
  102. pkgdir=../PKG
  103. elif [ -d ../../PKG/SRC ]; then
  104. pkgdir=../../PKG/SRC
  105. elif [ -d ../../PKG ]; then
  106. pkgdir=../../PKG
  107. else
  108. pkgdir=..
  109. fi
  110. echo "** rolling source bootstrap package:"
  111. echo " $pkgdir/$name-$version-$release.src.sh"
  112. rm -rf $tmpdir
  113. mkdir $tmpdir
  114. (cd $dstdir && tar cf - *) | (cd $tmpdir && tar xf -)
  115. (cd $srcdir && tar cf - *) | (cd $tmpdir && tar xf -)
  116. sed <$srcdir/aux.wrapsrc.sh >$pkgdir/$name-$version-$release.src.sh \
  117. -e "s;@DIR@;$name-$version-$release.src;" -e "s;@TGZ@;$name-$version-$release.src.tar.Z;"
  118. (cd $tmpdir && tar cf - *) | compress |\
  119. uuencode $name-$version-$release.src.tar.Z \
  120. | dd bs=64000 2>/dev/null >>$pkgdir/$name-$version-$release.src.sh
  121. exit 0
  122. fi
  123. ##
  124. ## calculate location id
  125. ##
  126. prefix=`echo "$prefix" | sed -e 's;//*;/;g' -e 's;/$;;'`
  127. if [ ".`expr $prefix : '/[^/][^/]*$'`" != .0 ]; then
  128. loc=`echo $prefix | cut -c2-4`
  129. else
  130. loc=`echo $prefix | sed -e 's;/\(.\)[^/]*;\1;g' | cut -c1-3`
  131. fi
  132. echo "++ location id: $loc"
  133. ##
  134. ## determine distribution directory
  135. ##
  136. V_rpm=`grep V_rpm $spec | head -1 | awk '{ printf("%s", $3); }'`
  137. if [ -f "../../DST/openpkg/rpm-${V_rpm}.tar.gz" ]; then
  138. distdir="`cd ../../DST/openpkg; pwd`" # developer only
  139. else
  140. distdir="`pwd`"
  141. fi
  142. echo "++ distribution directory: $distdir"
  143. ##
  144. ## perform prerequisite checks
  145. ##
  146. sh ./aux.prereq.sh source
  147. ##
  148. ## find reasonable run-time paths and tools
  149. ##
  150. # find reasonable temporary directory
  151. tmpdir="/tmp"
  152. test ".$TMPDIR" != . && tmpdir="$TMPDIR"
  153. test ".$TEMPDIR" != . && tmpdir="$TEMPDIR"
  154. # find reasonable safe program path
  155. test ".$PATH" = . && PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin"
  156. for dir in /usr/ccs/bin /usr/xpg4/bin; do
  157. test -d $dir && PATH="$PATH:$dir"
  158. done
  159. export PATH
  160. # find reasonable TAR
  161. l_tar=''
  162. for t in gtar tar; do
  163. for p in `IFS=":"; echo . $PATH`; do
  164. if [ -f "$p/$t" ]; then
  165. l_tar="$p/$t"
  166. break
  167. fi
  168. done
  169. [ ".$l_tar" != . ] && break
  170. done
  171. if [ ".$l_tar" = . ]; then
  172. echo "$0:FAILED: required TAR not found"
  173. exit 1
  174. fi
  175. # find required Make tool
  176. l_make=''
  177. for t in gmake make; do
  178. for p in `IFS=":"; echo . $PATH`; do
  179. if [ -f "$p/$t" ]; then
  180. l_make="$p/$t"
  181. break
  182. fi
  183. done
  184. [ ".$l_make" != . ] && break
  185. done
  186. if [ ".$l_make" = . ]; then
  187. echo "$0:FAILED: required Make tool not found"
  188. exit 1
  189. fi
  190. # find required [GNU] C Compiler
  191. l_cc=''
  192. for t in egcc ggcc gcc cc; do
  193. for p in `IFS=":"; echo . $PATH`; do
  194. if [ -f "$p/$t" ]; then
  195. # if [ ".`$p/$t --version 2>/dev/null | grep '[23]\.[789]'`" != . ]; then
  196. l_cc="$p/$t"
  197. break
  198. # fi
  199. fi
  200. done
  201. [ ".$l_cc" != . ] && break
  202. done
  203. if [ ".$l_cc" = . ]; then
  204. echo "$0:FAILED: required [GNU] C/C++ compiler not found"
  205. exit 1
  206. fi
  207. ##
  208. ## execute the spec file manually by emulating
  209. ## the behaviour of the OpenPKG RPM tool.
  210. ##
  211. # create script prolog
  212. prolog="$tmpdir/openpkg.boot.prolog.sh"
  213. cp /dev/null $prolog
  214. (
  215. echo "_specdir=`pwd`"
  216. echo "_sourcedir=$distdir"
  217. echo "_tmppath=$tmpdir"
  218. echo "_builddir=$tmpdir"
  219. echo "l_prefix=$prefix"
  220. echo "l_location=$loc"
  221. echo "l_buildroot=$tmpdir/$name-$version-root"
  222. echo "l_susr=$susr"
  223. echo "l_sgrp=$sgrp"
  224. echo "l_musr=$musr"
  225. echo "l_mgrp=$mgrp"
  226. echo "l_rusr=$rusr"
  227. echo "l_rgrp=$rgrp"
  228. echo "l_nusr=$nusr"
  229. echo "l_ngrp=$ngrp"
  230. echo "l_tar=$l_tar"
  231. echo "l_make=$l_make"
  232. echo "l_cc=$l_cc"
  233. grep '%define' $spec | \
  234. sed \
  235. -e 's:^%define *\([^ ]*\) *\(.*\):\1="\2":'
  236. grep "^[A-Za-z0-9]*: *" $spec | \
  237. sed \
  238. -e 's;^\([A-Za-z0-9]*\): *\(.*\)$;\1="\2";' \
  239. -e 's;^A;a;' -e 's;^B;b;' -e 's;^C;c;' -e 's;^D;d;' -e 's;^E;e;' \
  240. -e 's;^F;f;' -e 's;^G;g;' -e 's;^H;h;' -e 's;^I;i;' -e 's;^J;j;' \
  241. -e 's;^K;k;' -e 's;^L;l;' -e 's;^M;m;' -e 's;^N;n;' -e 's;^O;o;' \
  242. -e 's;^P;p;' -e 's;^Q;q;' -e 's;^R;r;' -e 's;^S;s;' -e 's;^T;t;' \
  243. -e 's;^U;u;' -e 's;^V;v;' -e 's;^W;w;' -e 's;^X;x;' -e 's;^Y;y;' \
  244. -e 's;^Z;z;' -e 's;^buildRoot;buildroot;'
  245. echo "RPM_BUILD_ROOT=\"%{buildroot}\""
  246. echo "RPM_BUILD_DIR=\"%{_builddir}\""
  247. echo "RPM_SOURCE_DIR=\"$distdir\""
  248. echo "export RPM_BUILD_ROOT"
  249. echo "export RPM_BUILD_DIR"
  250. echo "export RPM_SOURCE_DIR"
  251. echo "set -x"
  252. echo "umask 022"
  253. echo "cd \$RPM_BUILD_DIR"
  254. ) | sed -e 's;%{\([^}]*\)};${\1};g' >$prolog
  255. # install package via RPM spec file by faking a
  256. # sufficiently enough RPM run-time environment
  257. runscript () {
  258. step=$1
  259. script="$tmpdir/openpkg.boot.$step.sh"
  260. echo ". $prolog" >$script
  261. sed -e "/^%$step/,/^%/ p" -e 'd' <$spec | \
  262. sed -e '/^%/d' | \
  263. sed -e 's;%{SOURCE \([^ ]*\.tar[^ ]*\)};${RPM_DIST_DIR}/\1;g' \
  264. -e 's;%{SOURCE \([^ ]*\)};${RPM_SOURCE_DIR}/\1;g' | \
  265. sed -e 's;%{[?]\([^:]*\):\([^}]*\)};${\1+\2};g' \
  266. -e 's;%{![?]\([^:]*\):\([^}]*\)};${\1-\2};g' \
  267. -e 's;%{\([^}]*\)};${\1};g' >>$script
  268. echo "++ executing(%$step): sh $script"
  269. sh $script
  270. if [ $? -ne 0 ]; then
  271. rm -f $script
  272. echo "$0:ERROR: script returned non-null value"
  273. exit 1
  274. fi
  275. rm -f $script
  276. }
  277. runscript prep
  278. runscript build
  279. runscript install
  280. ##
  281. ## adjust build environment so that the installed
  282. ## "rpm" is actually useable, although it still resides in
  283. ## the temporary location instead of the real location.
  284. ##
  285. # suck in prolog in order to get variables from the spec file
  286. cwd=`pwd`
  287. . $prolog
  288. cd $cwd
  289. # suck in buildenv script in order to get musr/mgrp
  290. . $tmpdir/openpkg-*/.buildenv
  291. # create a custom "rpm" command
  292. echo "++ creating custom RPM command"
  293. rm -f $tmpdir/rpm >/dev/null 2>&1
  294. rmdir $tmpdir/rpm >/dev/null 2>&1
  295. if [ -d "$tmpdir/rpm" ]; then
  296. echo "$0:ERROR: directory $tmpdir/rpm exists, cannot create file with same name"
  297. exit 1
  298. fi
  299. if [ -f "$tmpdir/rpm" ]; then
  300. echo "$0:ERROR: file $tmpdir/rpm exists, cannot override"
  301. exit 1
  302. fi
  303. echo "#!/bin/sh" >$tmpdir/rpm
  304. echo "exec $RPM_BUILD_ROOT$prefix/lib/openpkg/rpm --rcfile $tmpdir/rpm.1 \"\$@\"" >>$tmpdir/rpm
  305. chmod a+x $tmpdir/rpm
  306. # direct our own "rpm" tool to adjusted macro sets
  307. sed <`SOURCE rpmrc` >$tmpdir/rpm.1 \
  308. -e "s;^\\(macrofiles:\\) .*;\\1 $tmpdir/rpm.2:$tmpdir/rpm.3;"
  309. # use an adjusted vendor macro set
  310. sed <$RPM_BUILD_ROOT$prefix/lib/openpkg/macros >$tmpdir/rpm.2 \
  311. -e "s;$prefix;$RPM_BUILD_ROOT$prefix;g"
  312. # override the vendor macro set
  313. sed <`SOURCE rpmmacros` >$tmpdir/rpm.3 \
  314. -e "s;@SUSR@;$susr;" \
  315. -e "s;@SGRP@;$sgrp;" \
  316. -e "s;@MUSR@;$musr;" \
  317. -e "s;@MGRP@;$mgrp;" \
  318. -e "s;@RUSR@;$rusr;" \
  319. -e "s;@RGRP@;$rgrp;" \
  320. -e "s;@NUSR@;$nusr;" \
  321. -e "s;@NGRP@;$ngrp;" \
  322. -e "s;@LOC@;$loc;" \
  323. -e "s;^\\(%l_root_install *\\)@l_prefix@;\\1 $prefix;" \
  324. -e "s;^\\(%l_root_rpm *\\)@l_prefix@;\\1 $RPM_BUILD_ROOT$prefix;" \
  325. -e "s;^\\(%_specdir *\\).*;\\1 `pwd`;" \
  326. -e "s;^\\(%_sourcedir *\\).*;\\1 $distdir;" \
  327. -e "s;^\\(%_builddir *\\).*;\\1 $tmpdir;" \
  328. -e "s;^\\(%_tmppath *\\).*;\\1 $tmpdir;" \
  329. -e "s;^\\(%_buildshell *\\).*;\\1 /bin/sh;"
  330. # use an own $HOME/.popt in order to make sure the "rpm"
  331. # tool is able to execute its sub-tools "rpm<x>".
  332. V_rpm=`grep V_rpm $spec | head -1 | awk '{ printf("%s", $3); }'`
  333. sed <$RPM_BUILD_ROOT$prefix/lib/openpkg/rpmpopt-${V_rpm} >$tmpdir/.popt \
  334. -e "s;^\\(rpm.*exec.*\\)\\(rpm[bdeukv]*\\);\\1$RPM_BUILD_ROOT$prefix/lib/openpkg/\\2;"
  335. # activate the .popt file
  336. HOME=$tmpdir
  337. export HOME
  338. ##
  339. ## now initialize the RPM database under the temporary install location
  340. ##
  341. echo "++ initializing RPM database"
  342. $tmpdir/rpm --initdb
  343. ##
  344. ## now turn over and re-iterate over the RPM spec, but this time
  345. ## with the real RPM tool.
  346. ##
  347. echo "++ re-iterating over RPM specification procedures"
  348. OPENPKG_BOOT=1
  349. export OPENPKG_BOOT
  350. $tmpdir/rpm -bb $spec
  351. ##
  352. ## and finally overwrite the installation again, but this time by
  353. ## installing officially through the "rpm" tool. This way we achieve
  354. ## that RPM is remembered as an RPM package in its own database. We
  355. ## just have to make sure the package is relocated while installing.
  356. ## For this we could use --prefix=$RPM_BUILD_ROOT$prefix, but this
  357. ## would create an incorrect filelist for "rpm" in the database.
  358. ## Instead we use the --justdb option which means "rpm" behaves as it
  359. ## would install into the real location, but does not actually install
  360. ## anything. But as a side-effect, the database is now correct.
  361. ##
  362. echo "++ overwriting RPM installation by installing via RPM itself"
  363. $tmpdir/rpm -Uvh --force --noscripts --justdb --ignoresize \
  364. $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-*.rpm
  365. ## Puhhhh!!! what a tricky bootstrapping procedure. But now we are
  366. ## mostly finished. All we finally have to do is to roll a bootstrap
  367. ## tarball in addition to the binary RPM and save the stuff in a
  368. ## permanent location.
  369. v="$version-$release"
  370. t="`$tmpdir/rpm --eval '%{_target}'`-$loc"
  371. # find a reasonable destination directory for packages
  372. if [ -d ../PKG/BIN ]; then
  373. dstdir=../PKG/BIN
  374. elif [ -d ../PKG ]; then
  375. dstdir=../PKG
  376. elif [ -d ../../PKG/BIN ]; then
  377. dstdir=../../PKG/BIN
  378. elif [ -d ../../PKG ]; then
  379. dstdir=../../PKG
  380. else
  381. dstdir=..
  382. fi
  383. # create Source-RPM file
  384. echo "++ creating bootstrap source RPM file"
  385. $tmpdir/rpm -bs --nodeps $spec
  386. cp $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.src.rpm $dstdir/
  387. rm -f $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.src.rpm
  388. # create Binary-RPM file
  389. echo "++ creating bootstrap binary RPM file"
  390. cp $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.$t.rpm $dstdir/
  391. rm -f $RPM_BUILD_ROOT$prefix/RPM/PKG/openpkg-$v.$t.rpm
  392. # create Binary-Bootstrap file
  393. echo "++ creating bootstrap binary shell script"
  394. cat $spec | sed -e "/^%pre$/,/^%/ p" -e 'd' | sed -e '/^%/d' -e 's/^ //' >$tmpdir/rpm.pre
  395. sed <`SOURCE aux.wrapbin.sh` \
  396. -e "s;@SUSR@;$susr;" -e "s;@SGRP@;$sgrp;" \
  397. -e "s;@MUSR@;$musr;" -e "s;@MGRP@;$mgrp;" \
  398. -e "s;@RUSR@;$rusr;" -e "s;@RGRP@;$rgrp;" \
  399. -e "s;@NUSR@;$nusr;" -e "s;@NGRP@;$ngrp;" \
  400. -e "s;@l_prefix@;$prefix;" -e "s;@TGZ@;openpkg-$v.$t.tar.Z;" \
  401. -e "/^@PRE@/r $tmpdir/rpm.pre" |\
  402. sed -e '/^@PRE@/d' >$dstdir/openpkg-$v.$t.sh
  403. files=`cat $spec |\
  404. sed -e '1,/%files/d' -e '/%clean/,$d' |\
  405. grep -v '^ *$' | grep -v '%defattr' |\
  406. sed -e 's;%config *;;' -e 's;%dir *;;' -e 's;%{l_prefix}/;;' -e 's;^ *;;' -e "s;%{V_rpm};${V_rpm};"`
  407. ( cd $RPM_BUILD_ROOT$prefix;
  408. $RPM_BUILD_ROOT$prefix/lib/openpkg/tar --no-recursion -cf - $files) |\
  409. compress | uuencode openpkg-$v.$t.tar.Z >>$dstdir/openpkg-$v.$t.sh
  410. # cleanup
  411. echo "++ cleaning up"
  412. rm -rf $RPM_BUILD_ROOT
  413. rm -rf $tmpdir/$name-$version
  414. rm -f $tmpdir/rpm $tmpdir/rpm.[123] $tmpdir/.popt $tmpdir/rpm.pre
  415. rm -f $prolog
  416. # final hint about results
  417. set +x
  418. echo "++ resulting files (placed into $dstdir):"
  419. (cd $dstdir; ls -l openpkg-$v.$t.sh openpkg-$v.$t.rpm openpkg-$v.src.rpm)