=pod =head1 NAME rc-sample -- B Example Use Cases =head1 DESCRIPTION This documents typical use cases for B. =head1 USE CASE: OpenPKG Run-Command Facility This describes how B is used as the B (http://www.openpkg.org/) run-command facility. First, the involved files: =over 4 =item F This is just the location of the B program. =item F This is the B configuration file, hard-coded into F at configure/build time with the Autoconf option C<--with-config=/cw/etc/rc.cf>. It is installed at B bootstrap time and used read-only. Dirs /cw/etc/rc.d:/cw/local/etc/rc.d Name rc.%s/rc.* ConfigDef (?<=^\s*)([a-zA-Z_][a-zA-Z_0-9]*)=("[^"]*"|'[^']*'|\S+) SectionDef (?<=^|\n)%([a-zA-Z][a-zA-Z0-9]*)(\s+-[a-zA-Z]\s*\S+)\s*\n(.+?)(?=\n%%\S+|$) ParamDef (?<=^|\s)-([a-zA-Z])\s*(\S+) SectionRef (?<=^\s*|;\s*)%([a-zA-Z][a-zA-Z0-9]*)(\s+[^\n]+)? ParamRef \$([0-9]) NameConfig config NameCommon common Execute root %s Execute !root sudo %s LineControl yes =item F (C<%common> extensions) This is the B Bourne-Shell script providing a set of reusable functions. It is installed at B bootstrap time and used read-only. opVarIsYes () { _var="${1}" eval "_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 return 1 ;; esac } opServiceEnabled () { opVarIsYes ${1}_enable } =item F This is the B configuration script where the administrator overrides the variables from the script's C<%config> sections. It it generated (as an empty file) on B bootstrap time and manually edited later to influence the behaviours of the package's run-command scripts (here F). foo_enable=yes foo_flags="--sample" =item F This is the example run-command script of an B package C. It is installed by package C and used read-only. #!/cw/etc/rc %config foo_enable=yes foo_flags="" %common foo_pidfile=/cw/var/foo/foo.pid %start -u root -p 100 if opServiceEnabled foo; then /cw/sbin/foo -p $foo_pidfile -S $foo_flags fi %stop -u root -p 100 if opServiceEnabled foo; then /cw/sbin/foo -p $foo_pidfile -K fi %restart -u root -p 100 if opServiceEnabled foo; then %stop sleep 1 %start fi %env if opServiceEnabled foo; then FOO=/cw/sbin/foo export FOO fi =back With this setup, the following use cases are possible: $ /cw/etc/rc --query "foo enabled: %{foo_enable}" foo enabled: yes $ _ $ /cw/etc/rc --config Configuration Variable Effective Value Default Value ------------------------ ------------------------- -- ------------------------- foo_enable "yes" == "yes" foo_flags "--sample" != "" $ _ $ /cw/etc/rc -v foo start start: foo $ _ $ /cw/etc/rc --print foo env # /cw/etc/rc.d/rc.foo 3 foo_enable=yes foo_flags="" # /cw/etc/rc.conf 1 foo_enable=yes foo_flags="--sample" # internal 0 . /cw/etc/rc.func # /cw/etc/rc.d/rc.foo 6 foo_pidfile=/cw/var/foo/foo.pid # /cw/etc/rc.d/rc.foo 22 if opServiceEnabled foo; then FOO="The Foo" export FOO fi $ _ $ eval `/cw/etc/rc --eval foo env` $ print $FOO The Foo $ _ =head1 USE CASE: Dynamic User Environment (DUE) =over 4 =item F<$HOME/.bashrc> cd () { eval `rc --eval --conf=$HOME/.duecf - leave` builtin cd ${1+"$@"} eval `rc --eval --conf=$HOME/.duecf - enter` } =item F<$HOME/.duecf> Dirs .:..// # current and all parent dirs Name .duerc NameGlobal $HOME/.dueglobal:/etc/dueglobal RequireUmask 022 RequireOwner %{USER} RequireGroup %{GROUP} Functions $HOME/.duefunc =item F<$HOME/.duefunc> # append (or optionally prepend) one or more directories (optionally # have to be existing) to a colon-separated path variable. In case a # directory already exists, it is first removed. # # Usage: duePathAdd [-p] [-e] [ ...] # Example: duePathAdd -e PATH /bin /sbin /usr/bin /usr/sbin /usr/ccs/bin # duePathAdd () { _prepend=0 _exists=0 while [ $# -gt 0 ]; do case $1 in -p ) _prepend=1; shift ;; -e ) _exists=1; shift ;; * ) break ;; esac done _var="$1" shift _edit_del="" _edit_add="" 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};'" else _edit_add="-e 's;^;${_dir}:;' ${_edit_add}" fi done 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 } # # remove one or more directories from a colon-separated path variable # # Usage: duePathDel [ ...] # Example: duePathDel PATH /bin /sbin /usr/bin /usr/sbin /usr/ccs/bin # duePathDel () { _var="$1" shift _edit="" 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 } =item F duePathAdd PATH $CWD/bin $CWD/sbin duePathAdd MANPATH $CWD/man duePathAdd INFOPATH $CWD/info duePathAdd LD_LIBRARY_PATH $CWD/lib duePathDel PATH $CWD/bin $CWD/sbin duePathDel MANPATH $CWD/man duePathDel INFOPATH $CWD/info duePathDel LD_LIBRARY_PATH $CWD/lib =item F<$HOME/.dueglobal> duePathAdd PATH /cw/bin /cw/sbin duePathAdd MANPATH /cw/man duePathAdd INFOPATH /cw/info duePathAdd LD_LIBRARY_PATH /cw/lib duePathDel PATH /cw/bin /cw/sbin duePathDel MANPATH /cw/man duePathDel INFOPATH /cw/info duePathDel LD_LIBRARY_PATH /cw/lib ... =cut