- (djm) [Makefile.in buildpkg.sh.in configure.ac openssh.xml.in]
   Support SMF in Solaris Packages if enabled by configure. Patch from
   Chad Mynhier, tested by dtucker@
diff --git a/buildpkg.sh.in b/buildpkg.sh.in
index a3960cb..a3b9014 100644
--- a/buildpkg.sh.in
+++ b/buildpkg.sh.in
@@ -46,6 +46,8 @@
 # end of sourced files
 #
 OPENSSHD=opensshd.init
+OPENSSH_MANIFEST=openssh.xml
+OPENSSH_FMRI=svc:/site/openssh:default
 
 PATH_GROUPADD_PROG=@PATH_GROUPADD_PROG@
 PATH_USERADD_PROG=@PATH_USERADD_PROG@
@@ -60,6 +62,10 @@
 /etc/rc1.d		\
 /etc/rc2.d		\
 /etc/opt		\
+/lib			\
+/lib/svc		\
+/lib/svc/method		\
+/lib/svc/method/site	\
 /opt			\
 /opt/bin		\
 /usr			\
@@ -82,6 +88,9 @@
 /var			\
 /var/opt		\
 /var/run		\
+/var/svc		\
+/var/svc/manifest	\
+/var/svc/manifest/site  \
 /var/tmp		\
 /tmp"
 
@@ -119,6 +128,12 @@
 	eval $confvar=`grep "^$confvar=" Makefile | cut -d = -f 2`
 done
 
+## Are we using Solaris' SMF?
+DO_SMF=0
+if egrep "^#define USE_SOLARIS_PROCESS_CONTRACTS" config.h > /dev/null 2>&1
+then
+	DO_SMF=1
+fi
 
 ## Collect value of privsep user
 for confvar in SSH_PRIVSEP_USER
@@ -168,10 +183,25 @@
 fi
 
 ## Setup our run level stuff while we are at it.
-mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d
+if [ $DO_SMF -eq 1 ]
+then
+	# For Solaris' SMF, /lib/svc/method/site is the preferred place
+	# for start/stop scripts that aren't supplied with the OS, and
+	# similarly /var/svc/manifest/site for manifests.
+	mkdir -p $FAKE_ROOT${TEST_DIR}/lib/svc/method/site
+	mkdir -p $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site
 
-cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
-chmod 744 $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
+	cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/lib/svc/method/site/${SYSVINIT_NAME}
+	chmod 744 $FAKE_ROOT${TEST_DIR}/lib/svc/method/site/${SYSVINIT_NAME}
+
+	cp ${OPENSSH_MANIFEST} $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site
+	chmod 644 $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site/${OPENSSH_MANIFEST}
+else
+	mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d
+
+	cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
+	chmod 744 $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
+fi
 
 [ "${PERMIT_ROOT_LOGIN}" = no ]  &&  \
 	perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \
@@ -221,15 +251,22 @@
 
 ## Build space file
 echo "Building space file..."
-cat > space << _EOF
-# extra space required by start/stop links added by installf in postinstall
+if [ $DO_SMF -eq 1 ]
+then
+	# XXX Is this necessary?  If not, remove space line from mk-proto.awk.
+	touch space
+else
+	cat > space << _EOF
+# extra space required by start/stop links added by installf 
+# in postinstall
 $TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1
 $TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1
 _EOF
-[ "$RC1_D" = no ]  ||  \
-echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space
-[ "$RCS_D" = yes ]  &&  \
-echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space
+	[ "$RC1_D" = no ]  ||  \
+	echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space
+	[ "$RCS_D" = yes ]  &&  \
+	echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space
+fi
 
 ## Build preinstall file
 echo "Building preinstall file..."
@@ -243,7 +280,16 @@
 
 cat >> preinstall << _EOF
 #
-[ "\${PRE_INS_STOP}" = "yes" ]  &&  ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
+if [ "\${PRE_INS_STOP}" = "yes" ]
+then
+	if [ $DO_SMF -eq 1 ] 
+	then
+		svcadm disable $OPENSSH_FMRI
+	else
+		${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
+	fi
+fi
+
 exit 0
 _EOF
 
@@ -265,28 +311,41 @@
 }
 
 # make rc?.d dirs only if we are doing a test install
-[ -n "${TEST_DIR}" ]  &&  {
+[ -n "${TEST_DIR}" ]  &&  [ $DO_SMF -ne 1 ] && {
 	[ "$RCS_D" = yes ]  &&  mkdir -p ${TEST_DIR}/etc/rcS.d
 	mkdir -p ${TEST_DIR}/etc/rc0.d
 	[ "$RC1_D" = no ]  ||  mkdir -p ${TEST_DIR}/etc/rc1.d
 	mkdir -p ${TEST_DIR}/etc/rc2.d
 }
 
-if [ "\${USE_SYM_LINKS}" = yes ]
+if [ $DO_SMF -eq 1 ]
 then
-	[ "$RCS_D" = yes ]  &&  \
-installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
-	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
-	[ "$RC1_D" = no ]  ||  \
-	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
-	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
+	# Delete the existing service, if it exists, then import the 
+	# new one.
+	if svcs $OPENSSH_FMRI > /dev/null 2>&1
+	then
+		svccfg delete -f $OPENSSH_FMRI
+	fi
+	# NOTE, if manifest enables sshd by default, this will actually
+	# start the daemon, which may not be what the user wants.
+	svccfg import ${TEST_DIR}/var/svc/manifest/site/$OPENSSH_MANIFEST
 else
-	[ "$RCS_D" = yes ]  &&  \
-installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
-	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
-	[ "$RC1_D" = no ]  ||  \
-	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
-	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
+	if [ "\${USE_SYM_LINKS}" = yes ]
+	then
+		[ "$RCS_D" = yes ]  &&  \
+	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
+		installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
+		[ "$RC1_D" = no ]  ||  \
+		installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
+		installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
+	else
+		[ "$RCS_D" = yes ]  &&  \
+	installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
+		installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
+		[ "$RC1_D" = no ]  ||  \
+		installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
+		installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
+	fi
 fi
 
 # If piddir doesn't exist we add it. (Ie. --with-pid-dir=/var/opt/ssh)
@@ -357,7 +416,17 @@
 		\$chroot ${PATH_PASSWD_PROG} -l $SSH_PRIVSEP_USER
 	}
 
-[ "\${POST_INS_START}" = "yes" ]  &&  ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} start
+if [ "\${POST_INS_START}" = "yes" ]
+then
+	if [ $DO_SMF -eq 1 ]
+	then
+		# See svccfg import note above.  The service may already
+		# be started.
+		svcadm enable $OPENSSH_FMRI
+	else
+		${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} start
+	fi
+fi
 exit 0
 _EOF
 
@@ -366,7 +435,12 @@
 cat > preremove << _EOF
 #! ${SCRIPT_SHELL}
 #
-${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
+if [ $DO_SMF -eq 1 ] 
+then
+	svcadm disable $OPENSSH_FMRI
+else
+	${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
+fi
 _EOF
 
 # local preremove changes here
@@ -381,6 +455,13 @@
 cat > postremove << _EOF
 #! ${SCRIPT_SHELL}
 #
+if [ $DO_SMF -eq 1 ]
+then
+	if svcs $OPENSSH_FMRI > /dev/null 2>&1
+	then
+		svccfg delete -f $OPENSSH_FMRI
+	fi
+fi
 _EOF
 
 # local postremove changes here
@@ -446,7 +527,45 @@
 
 _EOF
 
-cat >> request << _EOF
+if [ $DO_SMF -eq 1 ]
+then
+	# This could get hairy, as the running sshd may not be under SMF.
+	# We'll assume an earlier version of OpenSSH started via SMF.
+	cat >> request << _EOF
+PRE_INS_STOP=no
+POST_INS_START=no
+# determine if should restart the daemon
+if [ -s ${piddir}/sshd.pid  ] && \
+    /usr/bin/svcs $OPENSSH_FMRI 2>&1 | egrep "^online" > /dev/null 2>&1
+then
+	ans=\`ckyorn -d n \
+-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$?
+	case \$ans in
+		[y,Y]*)	PRE_INS_STOP=yes
+			POST_INS_START=yes
+			;;
+	esac
+
+else
+
+# determine if we should start sshd
+	ans=\`ckyorn -d n \
+-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$?
+	case \$ans in
+		[y,Y]*)	POST_INS_START=yes ;;
+	esac
+fi
+
+# make parameters available to installation service,
+# and so to any other packaging scripts
+cat >\$1 <<!
+PRE_INS_STOP='\$PRE_INS_STOP'
+POST_INS_START='\$POST_INS_START'
+!
+
+_EOF
+else
+	cat >> request << _EOF
 USE_SYM_LINKS=no
 PRE_INS_STOP=no
 POST_INS_START=no
@@ -487,6 +606,7 @@
 !
 
 _EOF
+fi
 
 # local request changes here
 [ -s "${PKG_REQUEST_LOCAL}" ]  &&  . ${PKG_REQUEST_LOCAL}