Subject: Changes to reference count directories
To: None <tech-pkg@NetBSD.org>
From: Johnny C. Lam <jlam@NetBSD.org>
List: tech-pkg
Date: 01/26/2005 08:51:41
--fUYQa+Pmc3FrFX/N
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Please comment on these changes by Friday, January 29 09:00:00 UTC.
Thanks!

	-- Johnny Lam <jlam@NetBSD.org>


  Summary
  =======

Reference count directories so that we know when it's safe to remove
a directory without impacting the remaining packages.  The reference
counts are stored in /var/db/pkgdir.  The install scripts are also
extended to allow for easy sanity-checking and fixing of the directories
present in the filesystem.

  Commit message
  ==============

Use reference counts to properly account for the creation and removal
of directories needed for the proper functioning of each package.

The +INSTALL script generates 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>.  Its 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 directories required by the package.

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.

Since the reference counts apply to the entire filesystem and are thus
global in nature, they cannot be stored within /usr/pkg, and they
should not be stored in any particular ${PKG_DBDIR}.  The global
reference counts are instead kept in /var/db/pkgdir by default, but
it may be changed by setting PKG_REFCOUNT_DBDIR appropriately in
/etc/mk.conf.

--fUYQa+Pmc3FrFX/N
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="refcount.diff"

Index: bsd.pkg.install.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/bsd.pkg.install.mk,v
retrieving revision 1.70
diff -u -r1.70 bsd.pkg.install.mk
--- bsd.pkg.install.mk	23 Jan 2005 20:45:22 -0000	1.70
+++ bsd.pkg.install.mk	26 Jan 2005 08:19:47 -0000
@@ -206,10 +206,67 @@
 MAKE_DIRS_PERMS?=	# empty
 OWN_DIRS?=		# empty
 OWN_DIRS_PERMS?=	# empty
-FILES_SUBST+=		MAKE_DIRS=${MAKE_DIRS:Q}
-FILES_SUBST+=		MAKE_DIRS_PERMS=${MAKE_DIRS_PERMS:Q}
-FILES_SUBST+=		OWN_DIRS=${OWN_DIRS:Q}
-FILES_SUBST+=		OWN_DIRS_PERMS=${OWN_DIRS_PERMS:Q}
+
+PKG_REFCOUNT_DBDIR?=	/var/db/pkgdir
+FILES_SUBST+=		PKG_REFCOUNT_DBDIR=${PKG_REFCOUNT_DBDIR:Q}
+
+DIRS_INSTALL_FILE=	${WRKDIR}/.dirsinstall
+INSTALL_EXTRA_TMPL+=	${DIRS_INSTALL_FILE}
+
+${DIRS_INSTALL_FILE}: ../../mk/install/dirs
+	${_PKG_SILENT}${_PKG_DEBUG}{					\
+	${ECHO} "# start of dirs-install";				\
+	${ECHO} "#";							\
+	${ECHO} "# Generate a +DIRS script that reference counts directories"; \
+	${ECHO} "# that are required for the proper functioning of the"; \
+	${ECHO} "# package.";						\
+	${ECHO} "#";							\
+	${ECHO} "case \$${STAGE} in";					\
+	${ECHO} "PRE-INSTALL)";						\
+	${ECHO} "	\$${CAT} > ./+DIRS << 'EOF_DIRS'";		\
+	${SED} ${FILES_SUBST_SED} ../../mk/install/dirs;		\
+	${ECHO} "";							\
+	${ECHO} "# !START DIRS";					\
+	case "${CONF_FILES}${CONF_FILES_PERMS}${SUPPORT_FILES}${SUPPORT_FILES_PERMS}" in \
+	"")	;;							\
+	*)	${ECHO} "# ${PKG_SYSCONFDIR} m" ;;			\
+	esac;								\
+	case "${RCD_SCRIPTS}" in					\
+	"")	;;							\
+	*)	${ECHO} "# ${RCD_SCRIPTS_DIR} m" ;;			\
+	esac;								\
+	eval set -- ${MAKE_DIRS} ;					\
+	while ${TEST} $$# -gt 0; do					\
+		dir="$$1"; shift;					\
+		${ECHO} "# $$dir m";					\
+	done;								\
+	eval set -- ${OWN_DIRS} ;					\
+	while ${TEST} $$# -gt 0; do					\
+		dir="$$1"; shift;					\
+		${ECHO} "# $$dir o";					\
+	done;								\
+	eval set -- ${MAKE_DIRS_PERMS} ;				\
+	while ${TEST} $$# -gt 0; do					\
+		dir="$$1"; owner="$$2"; group="$$3"; mode="$$4";	\
+		shift; shift; shift; shift;				\
+		${ECHO} "# $$dir $$owner $$group $$mode";		\
+	done;								\
+	eval set -- ${OWN_DIRS_PERMS} ;					\
+	while ${TEST} $$# -gt 0; do					\
+		dir="$$1"; owner="$$2"; group="$$3"; mode="$$4";	\
+		shift; shift; shift; shift;				\
+		${ECHO} "# $$dir o $$owner $$group $$mode";		\
+	done;								\
+	${ECHO} "# ~END DIRS";						\
+	${ECHO} "EOF_DIRS";						\
+	${ECHO} "	\$${CHMOD} +x ./+DIRS";				\
+	${ECHO} "	case \$${_PKG_CONFIG} in";			\
+	${ECHO} "	YES)	./+DIRS ADD \$${PKG_METADATA_DIR} ;;";	\
+	${ECHO} "	esac";						\
+	${ECHO} "	;;";						\
+	${ECHO} "esac";							\
+	} > ${.TARGET}.tmp;						\
+	${MV} -f ${.TARGET}.tmp ${.TARGET}
 
 # PKG_CREATE_USERGROUP indicates whether the INSTALL script should
 #	automatically add any needed users/groups to the system using
@@ -278,6 +335,7 @@
 FILES_SUBST+=		PERL5=${PERL5:Q}
 FILES_SUBST+=		PKG_ADMIN=${PKG_ADMIN_CMD:Q}
 FILES_SUBST+=		PKG_INFO=${PKG_INFO_CMD:Q}
+FILES_SUBST+=		PWD_CMD=${PWD_CMD:Q}
 FILES_SUBST+=		RM=${RM:Q}
 FILES_SUBST+=		RMDIR=${RMDIR:Q}
 FILES_SUBST+=		SED=${SED:Q}
@@ -295,6 +353,7 @@
 FILES_SUBST_SED=	${FILES_SUBST:S/=/@!/:S/$/!g/:S/^/ -e s!@/}
 
 INSTALL_SCRIPTS_ENV=	PKG_PREFIX=${PREFIX}
+INSTALL_SCRIPTS_ENV+=	PKG_METADATA_DIR=${_PKG_DBDIR}/${PKGNAME}
 
 .PHONY: pre-install-script post-install-script
 
Index: install/deinstall
===================================================================
RCS file: /cvsroot/pkgsrc/mk/install/deinstall,v
retrieving revision 1.29
diff -u -r1.29 deinstall
--- install/deinstall	11 Oct 2004 22:04:19 -0000	1.29
+++ install/deinstall	26 Jan 2005 08:19:47 -0000
@@ -45,34 +45,6 @@
 	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,12 @@
 		${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
+	if [ -x ./+DIRS ]; then
+		case ${_PKG_CONFIG} in
+		YES)	./+DIRS REMOVE ${PKG_METADATA_DIR} ;;
+		esac
+		./+DIRS CHECK-REMOVE
+	fi
 
 	if [ -n "${ALL_USERS}" -o -n "${ALL_GROUPS}" -o			\
 	     -n "${modified_files}" -o -n "${existing_dirs}" ]; then
Index: install/dirs
===================================================================
RCS file: install/dirs
diff -N install/dirs
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ install/dirs	26 Jan 2005 08:19:47 -0000
@@ -0,0 +1,207 @@
+#!@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.
+#
+# Lines between "!START DIRS" and "~END DIRS" are data read by this
+# script that names the directories that this package requires to exist
+# to function correctly, e.g.
+#
+#	# !START DIRS
+#	# /etc/foo m
+#	# /var/log/foo/tmp o foo-user foo-group 0700
+#	# ~END DIRS
+#
+CAT="@CAT@"
+CHGRP="@CHGRP@"
+CHMOD="@CHMOD@"
+CHOWN="@CHOWN@"
+ECHO="@ECHO@"
+GREP="@GREP@"
+LS="@LS@"
+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##*/}}
+
+case $ACTION in
+ADD)
+	${SED} -n "/^\# !START DIRS$/,/^\# ~END DIRS$/{s|^\# ||;p;}" ${SELF} |
+	${SORT} -u |
+	while read dir d_state d_user d_group d_mode; do
+		case $dir in
+		"!START"|"~END"|""|[!/]*)	continue ;;
+		esac
+		shadow_dir="${PKG_REFCOUNT_DBDIR}$dir"
+		perms="$shadow_dir/+PERMISSIONS"
+		preexist="$shadow_dir/+PREEXISTING"
+		token="$shadow_dir/${PKGNAME}"
+		${MKDIR} "$shadow_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
+		if ${TEST} -d "$dir"; then
+			if ${LS} -1a $dir | { while read i; do case $i in "."|"..") ;; *) exit 1 ;; esac; done; exit 0; }; then
+				${ECHO} "" > $preexist
+			fi
+		else
+			${MKDIR} $dir
+		fi
+		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 "/^\# !START DIRS$/,/^\# ~END DIRS$/{s|^\# ||;p;}" ${SELF} |
+	${SORT} -ru |
+	while read dir d_state d_user d_group d_mode; do
+		case $dir in
+		"!START"|"~END"|""|[!/]*)	continue ;;
+		esac
+		shadow_dir="${PKG_REFCOUNT_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 "/^\# !START DIRS$/,/^\# ~END DIRS$/{s|^\# ||;p;}" ${SELF} |
+	${SORT} -u |
+	while read dir d_state d_user d_group d_mode; do
+		case $dir in
+		"!START")
+			prev_dir="!START"
+			;;
+		"~END")
+			case $prev_dir in
+			"!START")
+				break
+				;;
+			*)
+				${ECHO} ""
+				${ECHO} "==========================================================================="
+				;;
+			esac
+			prev_dir="~END"
+			;;
+		""|[!/]*)
+			;;
+		*)
+			${TEST} -d "$dir" && continue
+			case $prev_dir in
+			"!START")
+				${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
+			prev_dir="$dir"
+			;;
+		esac
+	done
+	;;
+
+CHECK-REMOVE)
+	${SED} -n "/^\# !START DIRS$/,/^\# ~END DIRS$/{s|^\# ||;p;}" ${SELF} |
+	${SORT} -ru |
+	while read dir d_state d_user d_group d_mode; do
+		case $dir in
+		"~END")
+			prev_dir="~END"
+			;;
+		"!START")
+			case $prev_dir in
+			"~END")
+				break
+				;;
+			*)
+				${ECHO} ""
+				${ECHO} "==========================================================================="
+				;;
+			esac
+			prev_dir="!START"
+			;;
+		""|[!/]*)
+			;;
+		*)
+			${TEST} ! -d "$dir" && continue
+			case $d_state in
+			o)	;;
+			*)	continue ;;
+			esac
+			case $prev_dir in
+			"~END")
+				${ECHO} "==========================================================================="
+				${ECHO} "If you won't be using ${PKGNAME} any longer, you may want to remove"
+				${ECHO} ""
+				;;
+			esac
+			${ECHO} "	${dir}"
+			prev_dir="$dir"
+			;;
+		esac
+	done
+	;;
+
+esac
Index: install/header
===================================================================
RCS file: /cvsroot/pkgsrc/mk/install/header,v
retrieving revision 1.27
diff -u -r1.27 header
--- install/header	27 Dec 2004 06:41:50 -0000	1.27
+++ install/header	26 Jan 2005 08:19:47 -0000
@@ -35,6 +35,7 @@
 PERL5="@PERL5@"
 PKG_ADMIN="@PKG_ADMIN@"
 PKG_INFO="@PKG_INFO@"
+PWD_CMD="@PWD_CMD@"
 RM="@RM@"
 RMDIR="@RMDIR@"
 SED="@SED@"
@@ -49,6 +50,7 @@
 USERADD="@USERADD@"
 XARGS="@XARGS@"
 
+: ${PKG_METADATA_DIR=`${PWD_CMD}`}
 PKGBASE="@PKGBASE@"
 
 LOCALBASE="@LOCALBASE@"
@@ -74,11 +76,6 @@
 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 @@
 ALL_USERS=
 ALL_GROUPS=
 ALL_FILES=
-ALL_MAKE_DIRS=
-ALL_DIRS=
 VIEW_FILES=
 
 CONF_IGNORE_FILES="*[~#] *.OLD *.orig *,v .pkgsrc */.pkgsrc"
Index: install/install
===================================================================
RCS file: /cvsroot/pkgsrc/mk/install/install,v
retrieving revision 1.33
diff -u -r1.33 install
--- install/install	6 Jan 2005 23:44:35 -0000	1.33
+++ install/install	26 Jan 2005 08:19:48 -0000
@@ -2,20 +2,6 @@
 #
 # $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
-
 case ${STAGE} in
 PRE-INSTALL)
 	msginit
@@ -131,97 +117,17 @@
 			${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
         ;;
 
 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
+	if [ -x ./+DIRS ]; then
+		./+DIRS CHECK-ADD
 	fi
 
+	msginit
 	if [ "${_PKG_CONFIG}" = "YES" ]; then
 		if [ -n "${CONF_FILES}" -o				\
 		     -n "${CONF_FILES_PERMS}" -o			\

--fUYQa+Pmc3FrFX/N--