Browse Source

- rc: rewrite the implementation of --eval. It is now executed in a single GNU Bash script and hence can fully use all rc.func functionality. It also is executed in an emulated sub-shell environment and is allowed to "exit" without risking that the complete all-in-one script terminates. Finally, its resulting exported(!) environment variables are post-processed and are available to the caller in both Bourne-Shell and C-Shell syntax. - rc.func: switch language from standard Bourne-Shell to to GNU Bash in order to remove variable namespace pollution issues by the use of "local". - rpmmacros: add two convinience macros %{l_tmpdir} and %{l_tmpfile [arg]} for reasonable locations to a temporary directory (just %{_tmppath}) and a unique file there.

master
parent
commit
13a013e535
  1. 1
      openpkg/HISTORY
  2. 2
      openpkg/openpkg.spec
  3. 91
      openpkg/rc
  4. 98
      openpkg/rc.func
  5. 4
      openpkg/rpmmacros

1
openpkg/HISTORY

@ -2,6 +2,7 @@
2003
====
20030717 rc.func: add opService, switch to Bash; rc: rewrite --eval to use Bash; rpmmacros: add l_tmp{dir,file}
20030716 cleaned and enhanced "rc" again; added %{l_value} killer macro
20030715 work-off "rc" again: add -o/--output options, better cleanup, global return code
20030715 add to "rc" the -v/--verbose option again and provide terminal-detection

2
openpkg/openpkg.spec

@ -39,7 +39,7 @@
# o any cc(1)
# the package version/release
%define V_openpkg 20030716
%define V_openpkg 20030717
# the used software versions
%define V_rpm 4.0.2

91
openpkg/rc

@ -110,7 +110,11 @@ fi
rcconf="`echo $rcdir | sed -e 's;/rc.d$;/rc.conf;'`"
rcfunc="`echo $rcdir | sed -e 's;/rc.d$;/rc.func;'`"
# path to GNU Bash
bash="@l_prefix@/lib/openpkg/bash"
# extend run-time environment with local OpenPKG tools (shtool, rpmtool, etc)
PATH_ORIG="$PATH"
PATH="@l_prefix@/bin:$PATH"
PATH="@l_prefix@/sbin:$PATH"
PATH="@l_prefix@/lib/openpkg:$PATH"
@ -128,8 +132,9 @@ if [ $i -eq 10 ]; then
exit 1
fi
declare -r tmpdir
TMPDIR="$tmpdir"; export TMPDIR
TEMPDIR="$tmpdir"; export TEMPDIR
TMPDIR_ORIG="$TMPDIR"
TMPDIR="$tmpdir"
export TMPDIR
trap "trap - EXIT INT ABRT QUIT TERM; rm -rf $tmpdir >/dev/null 2>&1 || true" EXIT INT ABRT QUIT TERM
# determine reasonable temporary files
@ -411,6 +416,11 @@ for cmd in $cmds; do
# generate: inclusion of the application of override variables
echo ". $rcconf" >>$tmpfile
# for --eval redirect stderr and stdout (but remember stdout)
if [ ".$eval" = .1 ]; then
echo "exec 3<&1- 1>/dev/null 2>/dev/null" >>$tmpfile
fi
fi
# iterate over all packages (in priority order!) where the command
@ -447,12 +457,24 @@ for cmd in $cmds; do
fi
# now operate on the particular script
if [ ".$print" = .1 -o ".$eval" = .1 ]; then
# special case: under --print and --eval we just add the
# %common and command scripts to the generated output script
# and do not execute anything at this point.
if [ ".$print" = .1 ]; then
# special case: under --print we just add the %common and
# command scripts to the generated output script and do
# not execute anything at this point.
sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
elif [ ".$eval" = .1 ]; then
# special case: under --eval we just add the %common and
# command scripts to the generated output script and do
# not execute anything at this point. Additionally, we
# emulate a real sub-shell environment.
sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%common/d" -e '/^%.*/,$d'
echo "while [ 1 ]; do" >>$tmpfile
sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d' \
-e 's/^exit[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)exit[^;]*/\1break 99/g' \
-e 's/^return[^;]*/break 99/' -e 's/\([^a-zA-Z0-9_]\)return[^;]*/\1break 99/g'
echo "break" >>$tmpfile
echo "done" >>$tmpfile
else
# the regular case of executing the command script directly
@ -487,14 +509,13 @@ for cmd in $cmds; do
sed <$rcdir/rc.$s_name >>$tmpfile -e "1,/^%$cmd/d" -e '/^%.*/,$d'
# execute the generated script with GNU Bash
sh="@l_prefix@/lib/openpkg/bash"
if [ ".$user" != ".$s_user" ]; then
# execute as different user
su - $s_user -c "PATH=\"$PATH\"; $sh $tmpfile" >$outfile 2>$errfile
su - $s_user -c "PATH=\"$PATH\"; $bash $tmpfile" >$outfile 2>$errfile
rc=$?
else
# execute as current user
$sh $tmpfile >$outfile 2>$errfile
$bash $tmpfile >$outfile 2>$errfile
rc=$?
fi
if [ $rc -ne 0 ]; then
@ -525,16 +546,58 @@ for cmd in $cmds; do
# post-processing for each command
if [ ".$print" = .1 ]; then
# for --print just print the resulting script
# for --print just print the resulting script to stdout
cat $tmpfile
elif [ ".$eval" = .1 ]; then
# finish generation of temporary script by restoring stdout
# and printing the exported environment variables into a format
# suitable for evaluation by the callers shell.
echo "exec 1<&3-" >>$tmpfile
echo "unset PWD SHLVL" >>$tmpfile
echo "env |\\" >>$tmpfile
echo "egrep '^[A-Z]*=.' |\\" >>$tmpfile
echo "sed -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g' \\" >>$tmpfile
case $SHELL in
csh|*/csh|tcsh|*/tcsh )
echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/setenv \\1 \"\\2\"/'" >>$tmpfile
;;
* )
echo "-e 's/^\\([^=]*\\)=\\(.*\\)\$/\\1=\"\\2\"; export \\1/'" >>$tmpfile
;;
esac
# prepare temporary files
rm -f $outfile $errfile
touch $outfile $errfile
# now replace temporary script with its output
# by executing it and capturing its output
env -i \
HOME="$HOME" \
USER="$USER" \
LOGNAME="$LOGNAME" \
TERM="$TERM" \
PATH="$PATH_ORIG" \
MANPATH="$MANPATH" \
INFOPATH="$INFOPATH" \
LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
TMPDIR="$TMPDIR_ORIG" \
$bash --norc --noprofile --posix \
$tmpfile >$outfile 2>/dev/null
cp $outfile $tmpfile
# for --eval we cannot just print the resulting script because
# not all Bourne-Shell implementations like to "eval" large
# multi-line outputs. Hence we output a little one-liner which
# "sources" the script instead and cleans up. To make sure the
# "rm -rf $tmpdir" is not run by the automatic cleanup code,
# remove the EXIT trap.
echo ". $tmpfile; rm -rf $tmpdir 2>/dev/null || true"
# "sources" the script instead and cleans up.
case $SHELL in
csh|*/csh|tcsh|*/tcsh )
echo "source $tmpfile; rm -rf $tmpdir 2>/dev/null || true"
;;
* )
echo ". $tmpfile; rm -rf $tmpdir 2>/dev/null || true"
;;
esac
else
# for the execution situation just make sure we
# terminate the verbose message output.

98
openpkg/rc.func

@ -53,35 +53,35 @@ opWarn () {
# Example: opPathAdd -e PATH /bin /sbin /usr/bin /usr/sbin /usr/ccs/bin
#
opPathAdd () {
_prepend=0
_exists=0
local prepend=0
local exists=0
while [ $# -gt 0 ]; do
case $1 in
-p ) _prepend=1; shift ;;
-e ) _exists=1; shift ;;
-p ) prepend=1; shift ;;
-e ) exists=1; shift ;;
* ) break ;;
esac
done
_var="$1"
local var="$1"
shift
_edit_del=""
_edit_add=""
for _dir in "$@"; do
if [ ".${_exists}" = .1 ] && [ ! -d "${_dir}" ]; then
local edit_del=""
local edit_add=""
local dir
for dir in "$@"; do
if [ ".${exists}" = .1 ] && [ ! -d "${dir}" ]; then
continue
fi
_edit_del="${_edit_del} -e 's;^${_dir}\$;;' -e 's;^${_dir}:;;'"
_edit_del="${_edit_del} -e 's;:${_dir}:;:;' -e 's;:${_dir}\$;;'"
if [ ".${_prepend}" = .0 ]; then
_edit_add="${_edit_add} -e 's;\$;:${_dir};'"
edit_del="${edit_del} -e 's;^${dir}\$;;' -e 's;^${dir}:;;'"
edit_del="${edit_del} -e 's;:${dir}:;:;' -e 's;:${dir}\$;;'"
if [ ".${prepend}" = .0 ]; then
edit_add="${edit_add} -e 's;\$;:${dir};'"
else
_edit_add="-e 's;^;${_dir}:;' ${_edit_add}"
edit_add="-e 's;^;${dir}:;' ${edit_add}"
fi
done
if [ ".${_edit_del}${_edit_add}" != . ]; then
eval "${_var}=\`echo \"\$${_var}\" | sed ${_edit_del} ${_edit_add}\`"
if [ ".${edit_del}${edit_add}" != . ]; then
eval "${var}=\`echo \"\$${var}\" | sed ${edit_del} ${edit_add}\`"
fi
unset _prepend _exists _var _edit_del _edit_add _dir
}
#
@ -91,15 +91,15 @@ opPathAdd () {
# Example: opPathDel PATH /bin /sbin /usr/bin /usr/sbin /usr/ccs/bin
#
opPathDel () {
_var="$1"
local var="$1"
shift
_edit=""
for _dir in "$@"; do
_edit="${_edit} -e 's;^${_dir}\$;;' -e 's;^${_dir}:;;'"
_edit="${_edit} -e 's;:${_dir}:;:;' -e 's;:${_dir}\$;;'"
local edit=""
local dir
for dir in "$@"; do
edit="${edit} -e 's;^${dir}\$;;' -e 's;^${dir}:;;'"
edit="${edit} -e 's;:${dir}:;:;' -e 's;:${dir}\$;;'"
done
eval "${_var}=\`echo \"\$${_var}\" | sed ${_edit}\`"
unset _var _edit _dir
eval "${var}=\`echo \"\$${var}\" | sed ${edit}\`"
}
#
@ -109,25 +109,24 @@ opPathDel () {
# Example: if opVarIsYes foo; then ...
#
opVarIsYes () {
_var="${1}"
eval "_val=\"\$${_var}\""
case "${_val}" in
local var="${1}"
eval "local val=\"\$${var}\""
case "${val}" in
[Yy][Ee][Ss] | [Tt][Rr][Uu][Ee] | [Oo][Nn] | 1 )
unset _var _val
return 0
;;
[Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 )
unset _var _val
return 1
;;
*)
opWarn "variable \$${_var} is not set properly."
unset _var _val
opWarn "variable \$${var} is not set properly."
return 1
;;
esac
}
#
# FIXME: this function is now already deprecated!
#
# check whether a service is enabled.
#
@ -135,7 +134,26 @@ opVarIsYes () {
# Example: if opServiceEnabled openssh; then ...
#
opServiceEnabled () {
opVarIsYes ${1}_enable
opVarIsYes "`echo ${1} | sed -e 's;-;_;g'`_enable"
}
#
# check for service status enable/active/usable.
#
# Usage: opService <pkg> <var> <val>
# Example: if opService openssh enable yes; then ...
#
opService () {
local pkg="`echo ${1} | sed -e 's;-;_;g'`"
local var="${pkg}_${2}"
local chk="${3}"
eval "local val=\$${var}"
if [ ".$val" = . ]; then
eval `rc ${1} status`
eval "local val=\$${var}"
fi
test ".$val" = ".$chk"
return $?
}
#
@ -145,9 +163,9 @@ opServiceEnabled () {
# Example: opTmpDirGen openssh
#
opTmpDirGen () {
_tmpdir="@l_prefix@/RPM/TMP/${1}"
rm -rf ${_tmpdir} >/dev/null 2>&1 || true
(umask 077; mkdir ${_tmpdir} >/dev/null 2>&1 || true)
local tmpdir="@l_prefix@/RPM/TMP/${1}"
rm -rf ${tmpdir} >/dev/null 2>&1 || true
(umask 077; mkdir ${tmpdir} >/dev/null 2>&1 || true)
}
#
@ -157,9 +175,9 @@ opTmpDirGen () {
# Example: opTmpDirFile openssh 0 tmpfile
#
opTmpDirFile () {
_tmpdir="@l_prefix@/RPM/TMP/${1}"
eval "${3}=\"${_tmpdir}/${2}\""
(umask 077; touch "${_tmpdir}/${2}" >/dev/null 2>&1 || true)
local tmpdir="@l_prefix@/RPM/TMP/${1}"
eval "${3}=\"${tmpdir}/${2}\""
(umask 077; touch "${tmpdir}/${2}" >/dev/null 2>&1 || true)
}
#
@ -169,7 +187,7 @@ opTmpDirFile () {
# Example: opTmpDirDel openssh
#
opTmpDirDel () {
_tmpdir="@l_prefix@/RPM/TMP/${1}"
rm -rf ${_tmpdir} >/dev/null 2>&1 || true
local tmpdir="@l_prefix@/RPM/TMP/${1}"
rm -rf ${tmpdir} >/dev/null 2>&1 || true
}

4
openpkg/rpmmacros

@ -197,6 +197,10 @@
# path to local build root
%l_buildroot %{_tmppath}/%{name}-%{version}-root
# path to local temporary location
%l_tmpdir() %{_tmppath}
%l_tmpfile() %{l_tmpdir}/%{name}-%{version}-%{release}-tmp%{?1:-%1}
# executable path for %post/%pre
%_install_script_path @l_prefix@/bin:@l_prefix@/sbin:/bin:/sbin:/usr/bin:/usr/sbin

Loading…
Cancel
Save