diff options
author | jlam <jlam> | 2005-01-28 06:30:58 +0000 |
---|---|---|
committer | jlam <jlam> | 2005-01-28 06:30:58 +0000 |
commit | 9ade8283528d65a7740af92950f1f29f28cd9524 (patch) | |
tree | 9cf438e5d9a3ee9483f6b8a2483d71a25e7c5d0a /mk/install | |
parent | b15a511e19b63490b92b30c33f87720517b063f6 (diff) | |
download | pkgsrc-9ade8283528d65a7740af92950f1f29f28cd9524.tar.gz |
Use reference counts to properly account for the creation and removal
of directories needed for the proper functioning of each package.
The +INSTALL script unpacks a +DIRS script that adds and removes
directories. The +DIRS script entirely encapsulates the directory
creation and removal, and completely replaces the code in the
mk/install/install and mk/install/deinstall templates that handled
{MAKE,OWN}_DIRS and {MAKE,OWN}_DIRS_PERMS.
The +DIRS script is meant to be executed from within the package
meta-data directory, e.g. /var/db/pkg/<pkgname>. It's usage is:
./+DIRS ADD|REMOVE|CHECK-ADD|CHECK-REMOVE
The ADD and REMOVE actions cause the necessary directories to be added
or removed from the system. The CHECK-ADD and CHECK-REMOVE actions
print out informative messages prompting the user to either create or
remove some necessary directories.
The behaviour of "ADD" is such that if the directory already exists
on the system and is not already ref-counted, then that directory is
marked as "pre-existing". On "REMOVE", pre-existing directories are
left untouched on the filesystem.
At any time, the root user can sanity-check the directories needed by
packages by invoking all of the +DIRS scripts with the "CHECK-ADD"
action. If there are missing directories, then invoking all of the
+DIRS scripts with the "ADD" action will ensure that any missing
directories are created.
The reference counts database is stored in ${PKG_DBDIR}/.refcount.
The reference counts related to directories managed by the +DIRS script
are stored in ${PKG_DBDIR}/.refcount/dirs. If the directory reference
counts database is removed, then invoking all of the +DIRS scripts
with the "ADD" action will reconstruct the database; however, directories
may be marked as being pre-existing, so they won't be removed at
package de-installation (although a message will be displayed informing
the user that those directories can be removed).
Diffstat (limited to 'mk/install')
-rw-r--r-- | mk/install/deinstall | 90 | ||||
-rw-r--r-- | mk/install/dirs | 206 | ||||
-rw-r--r-- | mk/install/header | 11 | ||||
-rw-r--r-- | mk/install/install | 105 |
4 files changed, 220 insertions, 192 deletions
diff --git a/mk/install/deinstall b/mk/install/deinstall index 2cb733b8f8a..a6126b711de 100644 --- a/mk/install/deinstall +++ b/mk/install/deinstall @@ -1,6 +1,6 @@ # start of deinstall # -# $NetBSD: deinstall,v 1.29 2004/10/11 22:04:19 reed Exp $ +# $NetBSD: deinstall,v 1.30 2005/01/28 06:30:59 jlam Exp $ eval set -- ${PKG_USERS} for userset; do @@ -45,34 +45,6 @@ while [ $# -gt 0 ]; do VIEW_FILES="${VIEW_FILES} \"${file}\"" done -eval set -- ${PKG_SYSCONFDIR} ${RCD_SCRIPTS_DIR} ${MAKE_DIRS} -for dir; do - ALL_MAKE_DIRS="${ALL_MAKE_DIRS} \"${dir}\"" -done -eval set -- ${MAKE_DIRS_PERMS} -while [ $# -gt 0 ]; do - dir="$1"; owner="$2"; group="$3"; mode="$4" - shift; shift; shift; shift - ALL_MAKE_DIRS="${ALL_MAKE_DIRS} \"${dir}\"" -done -eval set -- ${ALL_MAKE_DIRS} ${OWN_DIRS} -for dir; do - ALL_DIRS="${ALL_DIRS} \"${dir}\"" -done -eval set -- ${OWN_DIRS_PERMS} -while [ $# -gt 0 ]; do - dir="$1"; owner="$2"; group="$3"; mode="$4" - shift; shift; shift; shift - ALL_DIRS="${ALL_DIRS} \"${dir}\"" -done -ALL_DIRS=` - ( eval set -- ${ALL_DIRS} - for dir; do - ${ECHO} "\"${dir}\"" - done - ) | ${SORT} -r -` - case ${STAGE} in VIEW-DEINSTALL) if [ "${_PKG_CONFIG}" = "YES" -a -n "${VIEW_FILES}" ]; then @@ -140,51 +112,9 @@ POST-DEINSTALL) ${RMDIR} -p `${DIRNAME} ${PKG_SYSCONFDIR}` 2>/dev/null || ${TRUE} fi - existing_dirs='' - eval set -- ${ALL_DIRS} - for dir; do - if [ "${_PKG_CONFIG}" = "YES" ]; then - if [ -f "${dir}/.pkgsrc" ]; then - dirowner=`${HEAD} -1 "${dir}/.pkgsrc"` - if [ "${dirowner}" = "${PKGBASE}" ]; then - ${RM} -f "${dir}/.pkgsrc" - ${RMDIR} -p "${dir}" 2>/dev/null || ${TRUE} - fi - fi - is_make_dir=` \ - eval set -- ${ALL_MAKE_DIRS}; \ - is_make_dir=0; \ - for make_dir; do \ - case "${make_dir}" in \ - ${dir}) is_make_dir=1; break ;; \ - esac; \ - done; \ - ${ECHO} ${is_make_dir} \ - ` - if [ ${is_make_dir} -eq 0 -a -d "${dir}" ]; then - existing_dirs="${existing_dirs} \"${dir}\"" - fi - else - case "${dir}" in - ${PKG_PREFIX}/*) - ${RMDIR} -p "${dir}" 2>/dev/null || ${TRUE} - ;; - esac - case "${dir}" in - # - # Don't bother the admin about the following dirs - # if they still exist. - # - ${PKG_SYSCONFBASE}|${RCD_SCRIPTS_DIR}) - ;; - *) - if [ -d "${dir}" ]; then - existing_dirs="${existing_dirs} \"${dir}\"" - fi - ;; - esac - fi - done + case ${_PKG_CONFIG} in + YES) ${TEST} -x ./+DIRS && ./+DIRS REMOVE ${PKG_METADATA_DIR} ;; + esac if [ -n "${ALL_USERS}" -o -n "${ALL_GROUPS}" -o \ -n "${modified_files}" -o -n "${existing_dirs}" ]; then @@ -225,17 +155,6 @@ EOF ${ECHO} " ${file}" done fi - if [ -n "${existing_dirs}" ]; then - ${CAT} << EOF - - * the following directories: - -EOF - eval set -- ${existing_dirs} - for dir; do - ${ECHO} " ${dir}" - done - fi if [ -n "${RCD_SCRIPTS}" ]; then ${CAT} << EOF @@ -247,6 +166,7 @@ EOF =========================================================================== EOF fi + ${TEST} -x ./+DIRS && ./+DIRS CHECK-REMOVE ;; esac diff --git a/mk/install/dirs b/mk/install/dirs new file mode 100644 index 00000000000..9f95755aa99 --- /dev/null +++ b/mk/install/dirs @@ -0,0 +1,206 @@ +#!@SH@ +# +# +DIRS - reference-counted directory management script +# +# Usage: ./+DIRS ADD|REMOVE [metadatadir] +# ./+DIRS CHECK-ADD|CHECK-REMOVE +# +# This script supports two actions, ADD and REMOVE, that will add or +# remove the directories needed by the package associated with +# <metadatadir>. The CHECK-ADD action will check whether any directories +# needed by the package are missing, and print an informative message +# noting those directories. The CHECK-REMOVE action will check whether +# any directories needed by the package still exist, and print an +# informative message noting those directories. The CHECK-ADD and +# CHECK-REMOVE actions return non-zero if they detect either missing +# or existing directories, respectively. +# +# Lines starting with "# DIR: " are data read by this script that +# name the directories that this package requires to exist to function +# correctly, e.g. +# +# # DIR: /etc/foo m +# # DIR: /var/log/foo/tmp mo foo-user foo-group 0700 +# +# The second field in each DIRS entry is a set of flags with the following +# meaning: +# +# m create (make) the directory when ADDing +# o directory is owned by the package +# +CAT="@CAT@" +CHGRP="@CHGRP@" +CHMOD="@CHMOD@" +CHOWN="@CHOWN@" +ECHO="@ECHO@" +GREP="@GREP@" +MKDIR="@MKDIR@" +MV="@MV@" +PWD_CMD="@PWD_CMD@" +RM="@RM@" +RMDIR="@RMDIR@" +SED="@SED@" +SORT="@SORT@" +TEST="@TEST@" +TRUE="@TRUE@" + +SELF=$0 +ACTION=$1 +PKG_METADATA_DIR="${2-`${PWD_CMD}`}" +PKG_REFCOUNT_DBDIR="@PKG_REFCOUNT_DBDIR@" +: ${PKGNAME=${PKG_METADATA_DIR##*/}} + +PKG_REFCOUNT_DIRS_DBDIR="${PKG_REFCOUNT_DBDIR}/dirs" + +exitcode=0 +case $ACTION in +ADD) + ${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -u | + while read dir d_flags d_user d_group d_mode; do + case $dir in + ""|[!/]*) continue ;; + esac + case $d_flags in + *m*) ;; + *) continue ;; + esac + shadow_dir="${PKG_REFCOUNT_DIRS_DBDIR}$dir" + perms="$shadow_dir/+PERMISSIONS" + preexist="$shadow_dir/+PREEXISTING" + token="$shadow_dir/${PKGNAME}" + if ${TEST} ! -d "$shadow_dir"; then + ${MKDIR} $shadow_dir + ${TEST} -d "$dir" && + ${ECHO} "${PKGNAME}" > $preexist + fi + ${MKDIR} $dir + if ${TEST} -f "$token" && \ + ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then + : + else + ${ECHO} "${PKG_METADATA_DIR}" >> $token + fi + case $d_user/$d_group/$d_mode in + [!/]*/[!/]*/[!/]*) + ${ECHO} "$d_user $d_group $d_mode" > $perms + ;; + esac + case $d_user/$d_group/$d_mode in + [!/]*/[!/]*/[!/]*) + ${CHOWN} $d_user $dir + ${CHGRP} $d_group $dir + ${CHMOD} $d_mode $dir + ;; + esac + done + ;; + +REMOVE) + ${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -ru | + while read dir d_flags d_user d_group d_mode; do + case $dir in + ""|[!/]*) continue ;; + esac + case $d_flags in + *m*) ;; + *) continue ;; + esac + shadow_dir="${PKG_REFCOUNT_DIRS_DBDIR}$dir" + perms="$shadow_dir/+PERMISSIONS" + preexist="$shadow_dir/+PREEXISTING" + token="$shadow_dir/${PKGNAME}" + tokentmp="$token.tmp.$$" + if ${TEST} -f "$token" && \ + ${GREP} "^${PKG_METADATA_DIR}$" $token >/dev/null; then + ${CAT} "$token" | ${GREP} -v "^${PKG_METADATA_DIR}$" > $tokentmp + case `${CAT} $tokentmp | ${SED} -n "$="` in + "") + ${TEST} -f "$preexist" || + { ${RMDIR} -p $dir 2>/dev/null || ${TRUE}; } + ${RM} -f $perms $preexist $token $token.tmp.* + ${RMDIR} -p $shadow_dir 2>/dev/null || ${TRUE} + ;; + *) + ${MV} -f $tokentmp $token + ;; + esac + fi + done + ;; + +CHECK-ADD) + ${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -u | + { while read dir d_flags d_user d_group d_mode; do + case $dir in + ""|[!/]*) continue ;; + *) ${TEST} -d "$dir" && continue ;; + esac + case $d_flags in + *m*) ;; + *) continue ;; + esac + case "$printed_header" in + yes) ;; + *) printed_header=yes + ${ECHO} "===========================================================================" + ${ECHO} "The following directories should be created for ${PKGNAME}:" + ${ECHO} "" + ;; + esac + case $d_user/$d_group/$d_mode in + [!/]*/[!/]*/[!/]*) + ${ECHO} " $dir (o=$d_user, g=$d_group, m=$d_mode)" + ;; + *) + ${ECHO} " $dir" + ;; + esac + done + case "$printed_header" in + yes) ${ECHO} "" + ${ECHO} "===========================================================================" + exit 1 + ;; + esac; } + ${TEST} $? -eq 0 || exitcode=1 + ;; + +CHECK-REMOVE) + ${SED} -n "/^\# DIR: /{s/^\# DIR: //;p;}" ${SELF} | ${SORT} -ru | + { while read dir d_flags d_user d_group d_mode; do + case $dir in + ""|[!/]*) continue ;; + *) ${TEST} -d "$dir" || continue ;; + esac + case $d_flags in + *o*) ;; + *) continue ;; + esac + shadow_dir="${PKG_REFCOUNT_DIRS_DBDIR}$dir" + ${TEST} -d "$shadow_dir" && continue # refcount isn't zero + case "$printed_header" in + yes) ;; + *) printed_header=yes + ${ECHO} "===========================================================================" + ${ECHO} "The following directories are no longer being used by ${PKGNAME}," + ${ECHO} "and they can be removed if no other packages are using them:" + ${ECHO} "" + ;; + esac + ${ECHO} " $dir" + done + case "$printed_header" in + yes) ${ECHO} "" + ${ECHO} "===========================================================================" + exit 1 + ;; + esac; } + ${TEST} $? -eq 0 || exitcode=1 + ;; + +*) + ${ECHO} "Usage: ./+DIRS ADD|REMOVE [metadatadir]" + ${ECHO} " ./+DIRS CHECK-ADD|CHECK-REMOVE" + ;; +esac +exit $exitcode diff --git a/mk/install/header b/mk/install/header index 17d41cbd972..6c5c41b3863 100644 --- a/mk/install/header +++ b/mk/install/header @@ -2,7 +2,7 @@ # # start of header # -# $NetBSD: header,v 1.27 2004/12/27 06:41:50 jlam Exp $ +# $NetBSD: header,v 1.28 2005/01/28 06:30:59 jlam Exp $ PKGNAME=$1 STAGE=$2 @@ -35,6 +35,7 @@ MV="@MV@" PERL5="@PERL5@" PKG_ADMIN="@PKG_ADMIN@" PKG_INFO="@PKG_INFO@" +PWD_CMD="@PWD_CMD@" RM="@RM@" RMDIR="@RMDIR@" SED="@SED@" @@ -49,6 +50,7 @@ TRUE="@TRUE@" USERADD="@USERADD@" XARGS="@XARGS@" +: ${PKG_METADATA_DIR=`${PWD_CMD}`} PKGBASE="@PKGBASE@" LOCALBASE="@LOCALBASE@" @@ -74,11 +76,6 @@ RCD_SCRIPTS="@RCD_SCRIPTS@" RCD_SCRIPTS_DIR="@RCD_SCRIPTS_DIR@" RCD_SCRIPTS_EXAMPLEDIR="@RCD_SCRIPTS_EXAMPLEDIR@" -MAKE_DIRS="@MAKE_DIRS@" -MAKE_DIRS_PERMS="@MAKE_DIRS_PERMS@" -OWN_DIRS="@OWN_DIRS@" -OWN_DIRS_PERMS="@OWN_DIRS_PERMS@" - PKG_SYSCONFBASE="@PKG_SYSCONFBASE@" PKG_SYSCONFDEPOTBASE="@PKG_SYSCONFDEPOTBASE@" PKG_SYSCONFBASEDIR="@PKG_SYSCONFBASEDIR@" @@ -96,8 +93,6 @@ PKG_SHELL="@PKG_SHELL@" ALL_USERS= ALL_GROUPS= ALL_FILES= -ALL_MAKE_DIRS= -ALL_DIRS= VIEW_FILES= CONF_IGNORE_FILES="*[~#] *.OLD *.orig *,v .pkgsrc */.pkgsrc" diff --git a/mk/install/install b/mk/install/install index d957682ef38..940f8004868 100644 --- a/mk/install/install +++ b/mk/install/install @@ -1,20 +1,6 @@ # start of install # -# $NetBSD: install,v 1.33 2005/01/06 23:44:35 jlam Exp $ - -if [ -z "${CONF_FILES}" -a -z "${CONF_FILES_PERMS}" -a \ - -z "${SUPPORT_FILES}" -a -z "${SUPPORT_FILES_PERMS}" -o \ - "${_PKG_CONFIG}" = "NO" ]; then - : -else - MAKE_DIRS="${MAKE_DIRS} \"${PKG_SYSCONFDIR}\"" -fi - -if [ -z "${RCD_SCRIPTS}" -o "${_PKG_RCD_SCRIPTS}" = "NO" ]; then - : -else - MAKE_DIRS="${MAKE_DIRS} \"${RCD_SCRIPTS_DIR}\"" -fi +# $NetBSD: install,v 1.34 2005/01/28 06:30:59 jlam Exp $ case ${STAGE} in PRE-INSTALL) @@ -131,97 +117,18 @@ PRE-INSTALL) ${LN} -sf $sysconfdir ${PKG_SYSCONFDIR} fi fi - if [ -n "${MAKE_DIRS}" -o -n "${OWN_DIRS}" -o \ - -n "${MAKE_DIRS_PERMS}" -o -n "${OWN_DIRS_PERMS}" ]; then - eval set -- ${MAKE_DIRS} ${OWN_DIRS} - for dir; do - if [ -d "${dir}" ]; then - continue - fi - if [ "${_PKG_CONFIG}" = "YES" ]; then - ${MKDIR} "${dir}" - if [ "${PKG_INSTALLATION_TYPE}" = "pkgviews" ]; then - case "${dir}" in - ${PKG_PREFIX}|${PKG_PREFIX}/*) ;; - *) ${ECHO} "${PKGBASE}" > "${dir}/.pkgsrc" ;; - esac - else - ${ECHO} "${PKGBASE}" > "${dir}/.pkgsrc" - fi - fi - done - eval set -- ${MAKE_DIRS_PERMS} ${OWN_DIRS_PERMS} - while [ $# -gt 0 ]; do - dir="$1"; owner="$2"; group="$3"; mode="$4" - shift; shift; shift; shift - if [ "${_PKG_CONFIG}" = "YES" ]; then - if [ ! -d "${dir}" ]; then - ${MKDIR} "${dir}" - if [ "${PKG_INSTALLATION_TYPE}" = "pkgviews" ]; then - case "${dir}" in - ${PKG_PREFIX}|${PKG_PREFIX}/*) ;; - *) ${ECHO} "${PKGBASE}" > "${dir}/.pkgsrc" ;; - esac - else - ${ECHO} "${PKGBASE}" > "${dir}/.pkgsrc" - fi - ${CHOWN} -R "${owner}" "${dir}" - ${CHGRP} -R "${group}" "${dir}" - ${CHMOD} -R "${mode}" "${dir}" - fi - fi - done - fi - if ! msgempty; then - ${ECHO} "===========================================================================" - msgprint - ${ECHO} "" - ${ECHO} "===========================================================================" - fi - if [ ${_pkg_exit} -gt 0 ]; then - exit ${_pkg_exit} - fi + case ${_PKG_CONFIG} in + YES) ${TEST} -x ./+DIRS && ./+DIRS ADD ${PKG_METADATA_DIR} ;; + esac ;; POST-INSTALL) # # Note any missing package directories. # - msginit - if [ -n "${MAKE_DIRS}" -o -n "${OWN_DIRS}" -o \ - -n "${MAKE_DIRS_PERMS}" -o -n "${OWN_DIRS_PERMS}" ]; then - _print_dir_header=1 - eval set -- ${MAKE_DIRS} ${OWN_DIRS} - for dir; do - if [ -d "${dir}" ]; then - continue - fi - if [ "${_PKG_CONFIG}" = "NO" ]; then - if [ ${_print_dir_header} -gt 0 ]; then - _print_dir_header=0 - msgadd "" - msgadd "The following directories should be created for ${PKGNAME}:" - msgadd "" - fi - msgadd "#${dir}" - fi - done - eval set -- ${MAKE_DIRS_PERMS} ${OWN_DIRS_PERMS} - while [ $# -gt 0 ]; do - dir="$1"; owner="$2"; group="$3"; mode="$4" - shift; shift; shift; shift - if [ "${_PKG_CONFIG}" = "NO" ]; then - if [ ${_print_dir_header} -gt 0 ]; then - _print_dir_header=0 - msgadd "" - msgadd "The following directories should be created for ${PKGNAME}:" - msgadd "" - fi - msgadd "#${dir} (o=${owner}, g=${group}, m=${mode})" - fi - done - fi + ${TEST} -x ./+DIRS && ./+DIRS CHECK-ADD + msginit if [ "${_PKG_CONFIG}" = "YES" ]; then if [ -n "${CONF_FILES}" -o \ -n "${CONF_FILES_PERMS}" -o \ |