update control to reflect move of primary repo to collab-maint
[debian/sudo] / pp
diff --git a/pp b/pp
index 2776485b663b7c2a5e82fd2e9c94a71066e53c8a..76b4d6e59e16443abc419a4b4694552b4736ede6 100755 (executable)
--- a/pp
+++ b/pp
@@ -1,7 +1,7 @@
 #!/bin/sh
-# (c) 2010 Quest Software, Inc. All rights reserved
-pp_revision="283"
- # Copyright 2010 Quest Software, Inc.  All rights reserved.
+# Copyright 2012 Quest Software, Inc. ALL RIGHTS RESERVED
+pp_revision="355"
+ # Copyright 2012 Quest Software, Inc.  ALL RIGHTS RESERVED.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions
@@ -31,7 +31,7 @@ pp_revision="283"
  # Please see <http://rc.quest.com/topics/polypkg/> for more information
 
 pp_version="1.0.0.$pp_revision"
-pp_copyright="Copyright 2010, Quest Software, Inc. All rights reserved."
+pp_copyright="Copyright 2012, Quest Software, Inc. ALL RIGHTS RESERVED."
 
 pp_opt_debug=false
 pp_opt_destdir="$DESTDIR"
@@ -802,7 +802,7 @@ pp_frontend_init () {
     version=
     summary="no summary"
     description="No description"
-    copyright="Copyright 2010 Quest Software, Inc. All rights reserved."
+    copyright="Copyright 2012 Quest Software, Inc. ALL RIGHTS RESERVED."
 
     #-- if the user supplied extra arguments on the command line
     #   then load them now.
@@ -961,7 +961,7 @@ pp_frontend () {
              fi
             test $# -eq 0 || pp_warn "ignoring extra arguments: $line"
             continue;;
-         %pre|%post|%preun|%postup|%postun|%files|%depend|%check)
+         %pre|%post|%preun|%postup|%postun|%files|%depend|%check|%conflict)
              pp_debug "processing new component section $*"
              s="$1"; shift
              if test $# -eq 0 || pp_is_qualifier "$1"; then
@@ -1056,7 +1056,7 @@ pp_frontend () {
                . $pp_wrkdir/tmp
                : > $pp_wrkdir/tmp
                ;;
-       %pre.*|%preun.*|%post.*|%postup.*|%postun.*|%depend.*|%check.*|%service.*|%fixup)
+       %pre.*|%preun.*|%post.*|%postup.*|%postun.*|%depend.*|%check.*|%conflict.*|%service.*|%fixup)
                 pp_debug "leaving $section: substituting $pp_wrkdir/tmp"
                 # cat $pp_wrkdir/tmp >&2    # debugging
                 $pp_opt_debug && pp_substitute < $pp_wrkdir/tmp >&2
@@ -1092,6 +1092,10 @@ pp_frontend () {
                pp_debug "Adding explicit dependency $@ to $cpt"
                echo "$@" >> $pp_wrkdir/%depend.$cpt
                ;;
+       %conflict.*)
+               pp_debug "Adding explicit conflict $@ to $cpt"
+               echo "$@" >> $pp_wrkdir/%conflict.$cpt
+               ;;
      esac
   done
   exec <&-
@@ -1554,6 +1558,8 @@ pp_backend_aix_init () {
         pp_aix_start_services_after_install=false
         pp_aix_init_services_after_install=true
 
+        pp_aix_sudo=sudo       # AIX package tools must run as root
+
         case "$pp_aix_os" in
             *) pp_readlink_fn=pp_ls_readlink;;  # XXX
         esac
@@ -1589,7 +1595,7 @@ pp_aix_detect_os () {
 
 pp_aix_version_fix () {
     typeset v
-    v=`echo $1 | tr -c -d '[0-9].\012'`
+    v=`echo $1 | sed 's/[-+]/./' | tr -c -d '[0-9].\012' | awk -F"." '{ printf "%d.%d.%d.%.4s\n", $1, $2, $3, $4 }' | sed 's/[.]*$//g'`
     if test x"$v" != x"$1"; then
         pp_warn "stripped version '$1' to '$v'"
     fi
@@ -1688,8 +1694,6 @@ pp_aix_inventory () {
       esac
       echo " type = $type"
       echo " class = inventory,apply,$fileset"
-      set -- `/bin/ls -ld "$pp_destdir$p" 2>/dev/null`
-      owner=$3 group=$4 size=$5
       if test x"$m" = x"-"; then m="$defm"; fi
       if test x"$o" = x"-"; then o="root"; fi
       if test x"$g" = x"-"; then g="system"; fi
@@ -1757,7 +1761,7 @@ pp_aix_add_service () {
 
        set -- $cmd
        cmd_cmd="$1"; shift
-       cmd_arg="$pp_aix_mkssys_cmd_args";
+       cmd_arg="${pp_aix_mkssys_cmd_args:-$*}";
 
        case "$stop_signal" in
                HUP) stop_signal=1;;
@@ -1787,11 +1791,12 @@ pp_aix_add_service () {
        cat <<-. >> $pp_wrkdir/%post.$svc
 svc=$svc
 uid=0
-cmd_cmd=$daemon
+cmd_cmd="$cmd_cmd"
 cmd_arg="$cmd_arg"
 stop_signal=$stop_signal
 force_signal=9
 srcgroup="$pp_aix_mkssys_group"
+instances_allowed=${pp_aix_mkssys_instances_allowed:--Q}
 
 lssrc -s \$svc > /dev/null 2>&1
 if [ \$? -eq 0 ]; then
@@ -1802,13 +1807,14 @@ if [ \$? -eq 0 ]; then
   rmsys -s \$svc > /dev/null 2>&1
 fi
 
-mkssys -s \$svc -u \$uid -p "\$cmd_cmd" \${cmd_arg:+-a "\$cmd_arg"} -S -n \$stop_signal -f 9 ${pp_aix_mkssys_args} \${srcgroup:+-G \$srcgroup}
+mkssys -s \$svc -u \$uid -p "\$cmd_cmd" \${cmd_arg:+-a "\$cmd_arg"} -S -n \$stop_signal -f 9 ${pp_aix_mkssys_args} \${srcgroup:+-G \$srcgroup} \$instances_allowed
 .
 
         #-- add code to start the service on reboot
         ${pp_aix_init_services_after_install} &&
           cat <<-. >> $pp_wrkdir/%post.$svc
-mkitab "\$svc:2:once:/usr/bin/startsrc -s \$svc" > /dev/null 2>&1
+id=\`echo "\$svc" | cut -c1-14\`
+mkitab "\$id:2:once:/usr/bin/startsrc -s \$svc" > /dev/null 2>&1
 .
 
        ${pp_aix_start_services_after_install} &&
@@ -1824,7 +1830,7 @@ mv $pp_wrkdir/%post.$svc $pp_wrkdir/%post.run
 
         ${pp_aix_init_services_after_install} &&
            pp_prepend $pp_wrkdir/%preun.$svc <<-.
-rmitab $svc
+rmitab `echo "$svc" | cut -c1-14` > /dev/null 2>&1
 .
        pp_prepend $pp_wrkdir/%preun.$svc <<-.
 stopsrc -s $svc >/dev/null 2>&1
@@ -1891,6 +1897,7 @@ pp_backend_aix () {
                     -o -s $pp_wrkdir/%pre.$cmp \
                     -o -s $pp_wrkdir/%post.$cmp \
                     -o -s $pp_wrkdir/%preun.$cmp \
+                    -o -s $pp_wrkdir/%postun.$cmp \
                     -o -s $pp_wrkdir/%check.$cmp
             then
                 content=B
@@ -1906,7 +1913,7 @@ pp_backend_aix () {
            bosboot=N; pp_contains_any "$pp_aix_bosboot" $cmp && bosboot=b
 
             echo $pp_aix_bff_name.$ex \
-                 ${pp_aix_version:-`pp_aix_version_fix "$version"`} \
+             `[ $pp_aix_version ] && pp_aix_version_fix $pp_aix_version || pp_aix_version_fix "$version"` \
                 1 $bosboot $content \
                 $pp_aix_lang "$summary $briefex"
            echo "["
@@ -1965,6 +1972,11 @@ pp_backend_aix () {
                        < $pp_wrkdir/%preun.$cmp
            fi
 
+           if test -r $pp_wrkdir/%postun.$cmp; then
+               pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.unpre_i \
+                       < $pp_wrkdir/%postun.$cmp
+           fi
+
            # remove empty files
            for f in $user_wrkdir/$pp_aix_bff_name.$ex.* $root_wrkdir/$pp_aix_bff_name.$ex.*; do
              if test ! -s "$f"; then
@@ -2043,7 +2055,7 @@ pp_backend_aix () {
        (cd $pp_destdir && pp_verbose  /usr/sbin/backup -i -q -p -f -) \
           < $pp_wrkdir/bff.list \
          > $pp_wrkdir/$outbff || pp_error "backup failed"
-        ${SUDO:-sudo} /usr/sbin/installp -l -d $pp_wrkdir/$outbff
+        $pp_aix_sudo /usr/sbin/installp -l -d $pp_wrkdir/$outbff
 }
 
 pp_backend_aix_cleanup () {
@@ -2051,7 +2063,7 @@ pp_backend_aix_cleanup () {
 }
 
 pp_backend_aix_names () {
-       echo "$name.${pp_aix_version:-`pp_aix_version_fix "$version"`}.bff"
+    echo "$name.`[ $pp_aix_version ] && pp_aix_version_fix $pp_aix_version || pp_aix_version_fix "$version"`.bff"
 }
 
 pp_backend_aix_install_script () {
@@ -2170,7 +2182,7 @@ pp_backend_aix_vas_platforms () {
     esac
 }
 pp_backend_aix_function () {
-    case $1 in
+    case "$1" in
     pp_mkgroup) cat <<'.';;
             /usr/sbin/lsgroup "$1" >/dev/null &&
                return 0
@@ -2224,6 +2236,7 @@ pp_backend_sd_init () {
     pp_sd_default_start=1           # config_file default start value
 
     pp_readlink_fn=pp_ls_readlink   # HPUX has no readlink
+    pp_shlib_suffix='.sl'           # .so on most other platforms
 
     pp_sd_detect_os
 }
@@ -2249,19 +2262,39 @@ pp_sd_write_files () {
     while read t m o g f p st; do
         line="                file"
         case "$f" in *v*) line="$line -v";; esac    # FIXME for uninstall
-        case $t in
-            f) dm=644;;
-            d) line="$line -t d"; p=${p%/}; dm=755;;
-            s) line="$line -t s";;
-        esac
+       case ${pp_sd_os} in
+           10.*)
+               case $t in
+                   f) dm=644;;
+                   d) p=${p%/}; dm=755;;
+               esac
+               ;;
+           *)
+               case $t in
+                   f) dm=644;;
+                   d) line="$line -t d"; p=${p%/}; dm=755;;
+                   s) line="$line -t s";;
+               esac
+               ;;
+       esac
 
         test x"$o" = x"-" && o=root
         test x"$g" = x"-" && g=sys
         test x"$m" = x"-" && m=$dm
 
         case $t in
-            s) echo "$line $st $p";;
-            *) echo "$line -o $o -g $g -m $m $pp_destdir$p $p";;
+            s)
+               # swpackage will make unqualified links relative to the
+               # current working (source) directory, not the destination;
+               # we need to qualify them to prevent this.
+               case "$st" in
+                   /*) echo "$line $st $p";;
+                   *) echo "$line `dirname $p`/$st $p";;
+               esac
+               ;;
+            *)
+               echo "$line -o $o -g $g -m $m $pp_destdir$p $p"
+               ;;
         esac
 
     done
@@ -2283,49 +2316,49 @@ pp_sd_service_group_script () {
 .
 
     cat <<-'.' >> $out
-        #-- starts services in order.. stops them all if any break
-        pp_start () {
-            undo=
-            for svc in $svcs; do
-                /sbin/init.d/$svc start
-               case $? in
-                 0|4)
-                   undo="$svc $undo"
-                   ;;
-                 *)
-                    if test -n "$undo"; then
-                        for svc in $undo; do
-                           /sbin/init.d/$svc stop
-                        done
-                        return 1
-                    fi
-                   ;;
-                esac
-            done
-            return 0
-        }
+       #-- starts services in order.. stops them all if any break
+       pp_start () {
+           undo=
+           for svc in \$svcs; do
+               /sbin/init.d/\$svc start
+               case \$? in
+                 0|4)
+                   undo="\$svc \$undo"
+                   ;;
+                 *)
+                   if test -n "\$undo"; then
+                       for svc in \$undo; do
+                           /sbin/init.d/\$svc stop
+                       done
+                       return 1
+                   fi
+                   ;;
+               esac
+           done
+           return 0
+       }
 
-        #-- stops services in reverse
-        pp_stop () {
-            reverse=
-            for svc in $svcs; do
-                reverse="$svc $reverse"
-            done
-            rc=0
-            for svc in $reverse; do
-                /sbin/init.d/$svc stop || rc=$?
-            done
-            return $rc
+       #-- stops services in reverse
+       pp_stop () {
+           reverse=
+           for svc in \$svcs; do
+               reverse="\$svc \$reverse"
+           done
+           rc=0
+           for svc in \$reverse; do
+               /sbin/init.d/\$svc stop || rc=\$?
+           done
+           return \$rc
         }
 
-        case $1 in
-            start_msg) echo "Starting $svcs";;
-            stop_msg)  echo "Stopping $svcs";;
+       case \$1 in
+           start_msg) echo "Starting \$svcs";;
+           stop_msg)  echo "Stopping \$svcs";;
            start)     pp_start;;
            stop)      pp_stop;;
-            *)        echo "usage: $0 {start|stop|start_msg|stop_msg}"
-                       exit 1;;
-        esac
+           *)         echo "usage: \$0 {start|stop|start_msg|stop_msg}"
+                      exit 1;;
+       esac
 .
 }
 
@@ -2376,61 +2409,61 @@ pp_sd_service_script () {
        }
 
        pp_stop () {
-           if test ! -s "$pidfile"; then
-               echo "Unable to stop $svc (no pid file)"
-               return 1
+           if test ! -s "\$pidfile"; then
+               echo "Unable to stop \$svc (no pid file)"
+               return 1
            else
-               read pid < "$pidfile"
-               if kill -0 "$pid" 2>/dev/null; then
-                   if kill -${stop_signal:-TERM} "$pid"; then
-                       rm -f "$pidfile"
-                       return 0
-                   else
-                       echo "Unable to stop $svc"
-                       return 1
-                   fi
-               else
-                   rm -f "$pidfile"
-                   return 0
-               fi
+               read pid < "\$pidfile"
+               if kill -0 "\$pid" 2>/dev/null; then
+                   if kill -${stop_signal:-TERM} "\$pid"; then
+                       rm -f "\$pidfile"
+                       return 0
+                   else
+                       echo "Unable to stop \$svc"
+                       return 1
+                   fi
+               else
+                   rm -f "\$pidfile"
+                   return 0
+               fi
            fi
        }
 
        pp_running () {
-           if test ! -s "$pidfile"; then
-               return 1
+           if test ! -s "\$pidfile"; then
+               return 1
            else
-               read pid < "$pidfile"
-               kill -0 "$pid" 2>/dev/null
+               read pid < "\$pidfile"
+               kill -0 "\$pid" 2>/dev/null
            fi
        }
 
-       case $1 in
-           start_msg) echo "Starting the $svc service";;
-           stop_msg)  echo "Stopping the $svc service";;
+       case \$1 in
+           start_msg) echo "Starting the \$svc service";;
+           stop_msg)  echo "Stopping the \$svc service";;
            start)
-                   if test -f "$config_file"; then
-                       . $config_file
-                   fi
-                   if pp_disabled; then
-                       exit 2
-                   elif pp_running; then
-                       echo "$svc already running";
-                       exit 0
-                   elif pp_start; then
-                       echo "$svc started";
-                       # rc(1M) says we should exit 4, but nobody expects it!
-                       exit 0
-                   else
-                       exit 1
-                   fi;;
+                   if test -f "\$config_file"; then
+                       . \$config_file
+                   fi
+                   if pp_disabled; then
+                       exit 2
+                   elif pp_running; then
+                       echo "\$svc already running";
+                       exit 0
+                   elif pp_start; then
+                       echo "\$svc started";
+                       # rc(1M) says we should exit 4, but nobody expects it!
+                       exit 0
+                   else
+                       exit 1
+                   fi;;
            stop)   if pp_stop; then
-                       echo "$svc stopped";
-                       exit 0
-                   else
-                       exit 1
-                   fi;;
-           *) echo "usage: $0 {start|stop|start_msg|stop_msg}"
+                       echo "\$svc stopped";
+                       exit 0
+                   else
+                       exit 1
+                   fi;;
+           *) echo "usage: \$0 {start|stop|start_msg|stop_msg}"
               exit 1;;
        esac
 .
@@ -2439,11 +2472,16 @@ pp_sd_service_script () {
 
 pp_sd_make_service () {
         typeset level startpriority stoppriority startlevels stoplevels
-        typeset svc svcvar
+        typeset svc svcvar symtype
 
         svc="$1"
        svcvar=`pp_makevar $svc`
 
+       case ${pp_sd_os} in
+           10.*) symtype="file";;
+           *) symtype="file -t s";;
+       esac
+
         # TODO: Figure out why this check is here
         #-- don't do anything if the script exists
         #if test -s "$pp_destdir/sbin/init.d/$svc"; then
@@ -2487,12 +2525,12 @@ pp_sd_make_service () {
 
         # create the symlinks
         test -z "$startlevels" || for level in $startlevels; do
-            echo "                file -t s" \
+            echo "                ${symtype}" \
                     "/sbin/init.d/$svc" \
                     "/sbin/rc$level.d/S$startpriority$svc"
         done
         test -z "$stoplevels" || for level in $stoplevels; do
-            echo "                file -t s" \
+            echo "                ${symtype}" \
                     "/sbin/init.d/$svc" \
                     "/sbin/rc$level.d/K$stoppriority$svc"
         done
@@ -2513,10 +2551,27 @@ pp_sd_control () {
     echo "                $ctrl $script"
 }
 
+pp_sd_depend () {
+    typeset _name _vers
+    while read _name _vers; do
+       case "$_name" in ""| "#"*) continue ;; esac
+       echo "                prerequisites $_name ${_vers:+r>= $_vers}"
+    done
+}
+
+pp_sd_conflict () {
+    typeset _name _vers
+    while read _name _vers; do
+       case "$_name" in ""| "#"*) continue ;; esac
+       echo "                exrequisites $_name ${_vers:+r>= $_vers}"
+    done
+}
+
 pp_backend_sd () {
-    typeset psf cpt svc outfile
+    typeset psf cpt svc outfile release swp_flags
 
     psf=$pp_wrkdir/psf
+    release="?.${pp_sd_os%.[0-9][0-9]}.*"
 
     echo "depot" > $psf
     echo "layout_version 1.0" >>$psf
@@ -2537,7 +2592,7 @@ pp_backend_sd () {
             copyright       "$copyright"
             machine_type    *
             os_name         HP-UX
-            os_release      ?.11.*
+            os_release      $release
             os_version      ?
             directory       /
             is_locatable    false
@@ -2563,6 +2618,10 @@ pp_backend_sd () {
                 title           "${summary:-cpt}"
                 revision        $version
 .
+        test -s $pp_wrkdir/%depend.$cpt &&
+              pp_sd_depend < $pp_wrkdir/%depend.$cpt >> $psf
+        test -s $pp_wrkdir/%conflict.$cpt &&
+              pp_sd_conflict < $pp_wrkdir/%conflict.$cpt >> $psf
 
        #-- make sure services are shut down during uninstall
         if test $cpt = run -a -n "$pp_services"; then
@@ -2618,10 +2677,15 @@ pp_backend_sd () {
     test -s $pp_wrkdir/%fixup && . $pp_wrkdir/%fixup
 
     outfile=`pp_backend_sd_names`
-    if pp_verbose ${pp_sd_sudo} /usr/sbin/swpackage \
-        -s $psf \
-        -x run_as_superuser=false \
-        -x media_type=tape \
+    case ${pp_sd_os} in
+       10.*)
+           swp_flags="-x target_type=tape"
+           ;;
+       *)
+           swp_flags="-x media_type=tape"
+           ;;
+    esac
+    if pp_verbose ${pp_sd_sudo} /usr/sbin/swpackage -s $psf $swp_flags \
         @ $pp_wrkdir/$outfile
     then
         pp_verbose ${pp_sd_sudo} /usr/sbin/swlist -l file -s $pp_wrkdir/$outfile
@@ -2719,7 +2783,7 @@ pp_backend_sd_init_svc_vars () {
     :
 }
 pp_backend_sd_function () {
-    case $1 in
+    case "$1" in
         pp_mkgroup) cat <<'.';;
            /usr/sbin/groupmod "$1" 2>/dev/null ||
                /usr/sbin/groupadd "$1"
@@ -2753,7 +2817,9 @@ pp_backend_solaris_init () {
        pp_solaris_category=
        pp_solaris_istates="s S 1 2 3"  # run-states when install is ok
        pp_solaris_rstates="s S 1 2 3"  # run-states when remove is ok
+       pp_solaris_maxinst=
        pp_solaris_vendor=
+       pp_solaris_pstamp=
        pp_solaris_copyright=
        pp_solaris_name=
        pp_solaris_desc=
@@ -2887,6 +2953,16 @@ pp_solaris_depend () {
     done
 }
 
+pp_solaris_conflict () {
+    typeset _name _vers
+    while read _name _vers; do
+       if test -n "$_name"; then
+           echo "I $_name $_name"
+           test -n "$_vers" && echo " $_vers"
+       fi
+    done
+}
+
 pp_solaris_space() {
     echo "$2:$3:$1" >> $pp_wrkdir/space.cumulative
 }
@@ -2903,14 +2979,14 @@ pp_solaris_proto () {
        typeset abi
 
        while read t m o g f p st; do
-         if test x"$o" = x"-"; then
-            o="root"
-          fi
-         if test x"$g" = x"-"; then
-            g="bin"
-          fi
+         # Use Solaris default mode, owner and group if all unspecified
+         if test x"$m$o$g" = x"---"; then
+           m="?"; o="?"; g="?"
+         fi
+         test x"$o" = x"-" && o="root"
          case "$t" in
-           f) test x"$m" = x"-" && m=444
+           f) test x"$g" = x"-" && g="bin"
+              test x"$m" = x"-" && m=444
               case "$f" in
                *v*) echo "v $1 $p=$pp_destdir$p $m $o $g";;
                *)   echo "f $1 $p=$pp_destdir$p $m $o $g";;
@@ -2929,12 +3005,15 @@ pp_solaris_proto () {
                  fi
               fi
                ;;
-           d) test x"$m" = x"-" && m=555
+           d) test x"$g" = x"-" && g="sys"
+              test x"$m" = x"-" && m=555
               echo "d $1 $p $m $o $g"
                ;;
-           s) test x"$m" = x"-" && m=777
-               test x"$m" = x"777" ||
+           s) test x"$g" = x"-" && g="bin"
+              test x"$m" = x"-" && m=777
+               if test x"$m" != x"777" -a x"$m" != x"?"; then
                   pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
+              fi
               echo "s $1 $p=$st $m $o $g"
                ;;
          esac
@@ -2982,8 +3061,12 @@ pp_backend_solaris () {
          echo "RSTATES=$pp_solaris_rstates" >> $pkginfo
        test -n "$pp_solaris_istates" &&
          echo "ISTATES=$pp_solaris_istates" >> $pkginfo
+       test -n "$pp_solaris_maxinst" &&
+         echo "MAXINST=$pp_solaris_maxinst" >> $pkginfo
        test -n "${pp_solaris_vendor:-$vendor}" &&
          echo "VENDOR=${pp_solaris_vendor:-$vendor}" >> $pkginfo
+       test -n "$pp_solaris_pstamp" &&
+         echo "PSTAMP=$pp_solaris_pstamp" >> $pkginfo
 
        if test -n "${pp_solaris_copyright:-$copyright}"; then
            echo "${pp_solaris_copyright:-$copyright}" > $pp_wrkdir/copyright
@@ -2993,6 +3076,7 @@ pp_backend_solaris () {
         #-- scripts to run before and after install
         : > $pp_wrkdir/postinstall
         : > $pp_wrkdir/preremove
+        : > $pp_wrkdir/postremove
        for _cmp in $pp_components; do
         #-- add the preinstall scripts in definition order
         if test -s $pp_wrkdir/%pre.$_cmp; then
@@ -3009,15 +3093,22 @@ pp_backend_solaris () {
             pp_solaris_procedure $_cmp preremove < $pp_wrkdir/%preun.$_cmp |
                     pp_prepend $pp_wrkdir/preremove
         fi
+        #-- add the postremove scripts in definition order
+        if test -s $pp_wrkdir/%postun.$_cmp; then
+            pp_solaris_procedure $_cmp postremove < $pp_wrkdir/%postun.$_cmp \
+                >> $pp_wrkdir/postremove
+        fi
         #-- Add the check script in definition order
         if test -s $pp_wrkdir/%check.$_cmp; then
             pp_solaris_procedure $_cmp checkinstall \
                         < $pp_wrkdir/%check.$_cmp \
                        >> $pp_wrkdir/checkinstall
         fi
-        #-- All dependencies are merged together for Solaris pkgs
+        #-- All dependencies and conflicts are merged together for Solaris pkgs
         test -s $pp_wrkdir/%depend.$_cmp &&
-              pp_solaris_depend < $pp_wrkdir/%depend.$_cmp > $pp_wrkdir/depend
+              pp_solaris_depend < $pp_wrkdir/%depend.$_cmp >> $pp_wrkdir/depend
+        test -s $pp_wrkdir/%conflict.$_cmp &&
+              pp_solaris_conflict < $pp_wrkdir/%conflict.$_cmp >> $pp_wrkdir/depend
        done
 
 
@@ -3028,11 +3119,12 @@ pp_backend_solaris () {
         test -n "$pp_services" &&
             for _svc in $pp_services; do
                 pp_load_service_vars $_svc
+                pp_solaris_smf $_svc
                 pp_solaris_make_service $_svc
                 pp_solaris_install_service $_svc | pp_prepend $pp_wrkdir/postinstall
-                pp_prepend $pp_wrkdir/preremove <<-.
-                    /etc/init.d/$_svc stop >/dev/null 2>/dev/null
-.
+                pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/preremove
+                pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/postremove
+                unset pp_svc_xml_file
             done
 
         test -n "$pp_service_groups" &&
@@ -3110,8 +3202,8 @@ if $pp_opt_debug; then
   echo "$prototype::"; cat $prototype
 fi >&2
 
-       pkgmk -a $pp_solaris_arch -d $pp_wrkdir/pkg \
-             -f $prototype || { error "pkgmk failed"; return; }
+       pkgmk -d $pp_wrkdir/pkg -f $prototype \
+               || { error "pkgmk failed"; return; }
         pkgtrans -s $pp_wrkdir/pkg \
                $pp_wrkdir/`pp_backend_solaris_names` \
                 ${pp_solaris_name:-$name} \
@@ -3264,7 +3356,7 @@ pp_backend_solaris_vas_platforms () {
     esac
 }
 pp_backend_solaris_function() {
-    case $1 in
+    case "$1" in
         pp_mkgroup) cat<<'.';;
            /usr/sbin/groupmod "$1" 2>/dev/null && return 0
             /usr/sbin/groupadd "$1"
@@ -3284,12 +3376,12 @@ pp_backend_solaris_function() {
 }
 
 pp_backend_solaris_init_svc_vars () {
-    pp_solaris_smf_category=
+    _smf_category=${pp_solaris_smf_category:-application}
+    _smf_method_envvar_name=${smf_method_envvar_name:-"PP_SMF_SERVICE"}
     pp_solaris_service_shell=/sbin/sh
 }
 
 pp_solaris_init_svc () {
-    smf_category=${pp_solaris_smf_category:-application}
     smf_version=1
     smf_type=service
     solaris_user=
@@ -3307,40 +3399,118 @@ pp_solaris_init_svc () {
 }
 
 pp_solaris_smf () {
-    typeset f
-    f=/var/svc/manifest/$smf_category/$1
+    typeset f _pp_solaris_service_script svc _pp_solaris_manpage
+
+    pp_solaris_name=${pp_solaris_name:-$name}
+    pp_solaris_manpath=${pp_solaris_manpath:-"/usr/share/man"}
+    pp_solaris_mansect=${pp_solaris_mansect:-1}
+    smf_start_timeout=${smf_start_timeout:-60}
+    smf_stop_timeout=${smf_stop_timeout:-60}
+    smf_restart_timeout=${smf_restart_timeout:-60}
+
+    svc=${pp_solaris_smf_service_name:-$1}
+    _pp_solaris_service_script=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
+    _pp_solaris_manpage=${pp_solaris_manpage:-$svc}
+
+    if [ -z $pp_svc_xml_file ]; then
+        pp_svc_xml_file="/var/svc/manifest/$_smf_category/$svc.xml"
+        echo "## Generating the smf service manifest file for $pp_svc_xml_file"
+    else
+        echo "## SMF service manifest file already defined at $pp_svc_xml_file"
+        if [ -z $pp_solaris_smf_service_name ] || [ -z $pp_solaris_smf_category ] || [ -z $pp_solaris_service_script ] || [ -z $smf_method_envvar_name ]; then
+          pp_error "All required variables are not set.\n"\
+                   "When using a custom manifest file all of the following variables must be set:\n"\
+                   "pp_solaris_smf_service_name, pp_solaris_smf_category, pp_solaris_service_script and smf_method_envvar_name.\n\n"\
+                   "Example:\n"\
+                   " \$pp_solaris_smf_category=application\n"\
+                   " \$pp_solaris_smf_service_name=pp\n\n"\
+                   "  <service name='application/pp' type='service' version='1'>\n\n"\
+                   "Example:\n"\
+                   " \$pp_solaris_service_script=/etc/init.d/pp\n\n"\
+                   "  <exec_method type='method' name='start' exec='/etc/init.d/pp' />\n\n"\
+                   "Example:\n"\
+                   " \$smf_method_envvar_name=PP_SMF_SERVICE\n\n"\
+                   "  <method_environment>\n"\
+                   "    <envvar name='PP_SMF_SERVICE' value='1'/>\n"\
+                   "  </method_environment>\n"
+
+          return 1
+        fi
+        return 0
+    fi
+
+    f=$pp_svc_xml_file
     pp_add_file_if_missing $f ||
         return 0
+    pp_solaris_add_parent_dirs "$f"
+
+    _pp_solaris_smf_dependencies="
+          <dependency name='pp_local_filesystems'
+                grouping='require_all'
+                restart_on='none'
+                type='service'>
+                <service_fmri value='svc:/system/filesystem/local'/>
+          </dependency>
+
+          <dependency name='pp_single-user'
+                grouping='require_all'
+                restart_on='none'
+                type='service'>
+                <service_fmri value='svc:/milestone/single-user' />
+          </dependency>
+"
+    _pp_solaris_smf_dependencies=${pp_solaris_smf_dependencies:-$_pp_solaris_smf_dependencies}
 
     cat <<-. >$pp_destdir$f
-       <?xml version="1.0"?>
-        <!--
-            $copyright
-            Generated by PolyPackage $pp_version
-       -->
-
-        <service name='$smf_category/$1'
-                 type='$smf_type'
-                 version='$smf_version'>
-
-            <single_instance />
-
-            <exec_method type='method' name='start'
-                exec=''
-                timeout_seconds='60'>
-                <method_context>
-                  <method_credential user='${solaris_user:-$user}' />
-                </method_context>
-            </exec>
-
-            <exec_method type='method' name='stop'
-                exec=':kill -${solaris_stop_signal:-$stop_signal}'>
-                <method_context>
-                  <method_credential user='${solaris_user:-$user}' />
-                </method_context>
-            </exec>
-
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
+<!--
+       $copyright
+        Generated by PolyPackage $pp_version
+-->
+
+    <service_bundle type='manifest' name='${pp_solaris_name}:${svc}' >
+          <service name='$_smf_category/$svc'
+                type='$smf_type'
+                version='$smf_version'>
+
+          <create_default_instance enabled='false'/>
+
+          <single_instance />
+
+          $_pp_solaris_smf_dependencies
+
+          $pp_solaris_smf_additional_dependencies
+
+          <method_context>
+                <method_credential user='${solaris_user:-$user}' />
+                <method_environment>
+                    <envvar name='$_smf_method_envvar_name' value='1'/>
+                </method_environment>
+          </method_context>
+
+          <exec_method type='method' name='start'
+                exec='$_pp_solaris_service_script start'
+                timeout_seconds='$smf_start_timeout' />
+
+          <exec_method type='method' name='stop'
+                exec='$_pp_solaris_service_script stop'
+                timeout_seconds='$smf_stop_timeout' />
+
+          <exec_method type='method' name='restart'
+                exec='$_pp_solaris_service_script restart'
+                timeout_seconds='$smf_restart_timeout' />
+
+          <template>
+              <common_name>
+                  <loctext xml:lang='C'>$description</loctext>
+              </common_name>
+              <documentation>
+                  <manpage title='$pp_solaris_manpage' section='$pp_solaris_mansect' manpath='$pp_solaris_manpath'/>
+              </documentation>
+          </template>
         </service>
+    </service_bundle>
 .
 }
 
@@ -3352,8 +3522,9 @@ pp_solaris_make_service_group () {
     file="/etc/init.d/$group"
     out="$pp_destdir$file"
 
-    #-- return if the script is supplued already
+    #-- return if the script is supplied already
     pp_add_file_if_missing "$file" run 755 || return 0
+    pp_solaris_add_parent_dirs "$file"
 
     echo "#! /sbin/sh" > $out
     echo "# polypkg service group script for these services:" >> $out
@@ -3411,22 +3582,59 @@ pp_solaris_make_service_group () {
 .
 }
 
-
 pp_solaris_make_service () {
     typeset file out _cmd svc
 
-    svc="$1"
-    file="/etc/init.d/$svc"
+    svc="${pp_solaris_smf_service_name:-$1}"
+    file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
     out="$pp_destdir$file"
 
-
     #-- return if we don't need to create the init script
     pp_add_file_if_missing "$file" run 755 ||
         return 0
+    pp_solaris_add_parent_dirs "$file"
 
     echo "#! /sbin/sh" >$out
     echo "#-- This service init file generated by polypkg" >>$out
 
+    #-- Start SMF integration.
+    if [ -n "$pp_svc_xml_file" ] ; then
+        cat <<_EOF >>$out
+if [ -x /usr/sbin/svcadm ] && [ "x\$1" != "xstatus" ] && [ "t\$$_smf_method_envvar_name" = "t" ] ; then
+    case "\$1" in
+        start)
+            echo "starting $svc"
+            /usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
+            /usr/sbin/svcadm enable -s $_smf_category/$svc
+            RESULT=\$?
+            if [ "\$RESULT" -ne 0 ] ; then
+                echo "Error \$RESULT starting $svc" >&2
+            fi
+            ;;
+        stop)
+            echo "stopping $svc"
+            /usr/sbin/svcadm disable -ts $_smf_category/$svc
+           RESULT=0
+            ;;
+        restart)
+            echo "restarting $svc"
+            /usr/sbin/svcadm disable -ts $_smf_category/$svc
+            /usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
+            /usr/sbin/svcadm enable -s $_smf_category/$svc
+            RESULT=\$?
+            if [ "\$RESULT" -ne 0 ] ; then
+                echo "Error \$RESULT starting $svc" >&2
+            fi
+            ;;
+        *)
+            echo "Usage: $file {start|stop|restart|status}" >&2
+            RESULT=1
+    esac
+    exit $RESULT
+fi
+_EOF
+    fi
+
     #-- construct a start command that builds a pid file as needed
     #   and forks the daemon
     _cmd="$cmd";
@@ -3465,8 +3673,8 @@ pp_solaris_make_service () {
 
         # returns true if $svc is running
         pp_running () {
-            test -r "$pidfile" &&
-            read pid junk < "$pidfile" &&
+            test -s "$pidfile" || return 1
+            read pid junk < "$pidfile" 2>/dev/null
             test ${pid:-0} -gt 1 &&
             kill -0 "$pid" 2>/dev/null
         }
@@ -3528,13 +3736,33 @@ pp_solaris_make_service () {
 .
 }
 
+pp_solaris_remove_service () {
+    typeset file svc
+
+    svc="${pp_solaris_smf_service_name:-$1}"
+    file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
+
+    echo '
+'$file' stop >/dev/null 2>/dev/null
+if [ "x${PKG_INSTALL_ROOT}" = 'x' ]; then
+    if [ -x /usr/sbin/svcadm ] ; then
+        # Likely un-needed, but just in case.
+        /usr/sbin/svcadm disable -s '$svc' 2>/dev/null
+        /usr/sbin/svccfg delete '$svc' 2>/dev/null
+    fi
+fi
+    '
+}
 
 pp_solaris_install_service () {
-    typeset s k l
-    s="${solaris_sysv_init_start}$1"
-    k="${solaris_sysv_init_kill}$1"
+    typeset s k l file svc
+
+    svc="${pp_solaris_smf_service_name:-$1}"
+    file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
+
+    s="${solaris_sysv_init_start}$svc"
+    k="${solaris_sysv_init_kill}$svc"
 
-    echo 'case " $SERVICES " in *" '$1' "*)'
     echo '
 if [ "x${PKG_INSTALL_ROOT}" != "x" ]; then
   if [ -x ${PKG_INSTALL_ROOT}/usr/sbin/svcadm ]; then
@@ -3544,41 +3772,54 @@ if [ "x${PKG_INSTALL_ROOT}" != "x" ]; then
         for state in ${solaris_sysv_init_start_states}; do
             l="/etc/rc$state.d/$s"
             echo "echo '$l'"
-            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
+            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
             pp_solaris_space /etc/rc$state.d 0 1
         done
     test -n "${solaris_sysv_init_kill_states}" &&
         for state in ${solaris_sysv_init_kill_states}; do
             l="/etc/rc$state.d/$k"
             echo "echo '$l'"
-            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
+            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
             pp_solaris_space /etc/rc$state.d 0 1
         done
     echo '
   fi
 else
     if [ -x /usr/sbin/svcadm ]; then
-        echo "Registering '$1' with SMF"
-        /usr/sbin/svcadm disable -s '$1' 2>/dev/null
-        /usr/sbin/svccfg delete '$1' 2>/dev/null
-        /usr/sbin/svccfg import '$pp_svc_xml_file' 2>/dev/null
+        echo "Registering '$svc' with SMF"
+        /usr/sbin/svcadm disable -s '$svc' 2>/dev/null
+        /usr/sbin/svccfg delete '$svc' 2>/dev/null
+        /usr/sbin/svccfg import '$pp_svc_xml_file'
     else'
     test -n "${solaris_sysv_init_start_states}" &&
         for state in ${solaris_sysv_init_start_states}; do
             l="/etc/rc$state.d/$s"
             echo "echo '$l'"
-            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
+            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
             pp_solaris_space /etc/rc$state.d 0 1
         done
     test -n "${solaris_sysv_init_kill_states}" &&
         for state in ${solaris_sysv_init_kill_states}; do
             l="/etc/rc$state.d/$k"
             echo "echo '$l'"
-            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
+            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
             pp_solaris_space /etc/rc$state.d 0 1
         done
-    echo " :;; esac"
+    echo '
+    fi
+fi'
+}
+
+pp_solaris_add_parent_dirs () {
+    typeset dir
 
+    dir=${1%/*}
+    while test -n "$dir"; do
+       if awk "\$6 == \"$dir/\" {exit 1}" < $pp_wrkdir/%files.run; then
+           echo "d - - - - $dir/" >> $pp_wrkdir/%files.run
+       fi
+       dir=${dir%/*}
+    done
 }
 
 pp_platforms="$pp_platforms deb"
@@ -3666,11 +3907,37 @@ pp_deb_detect_arch () {
    pp_deb_arch_std=`uname -m`
 }
 
+pp_deb_sanitize_version() {
+    echo "$@" | tr -d -c '[:alnum:].+-:~'
+}
+
+pp_deb_version_final() {
+    if test -n "$pp_deb_version"; then
+        # Don't sanitize; assume the user is sane (hah!)
+        echo "$pp_deb_version"
+    else
+        pp_deb_sanitize_version "$version"
+    fi
+}
+
+pp_deb_conflict () {
+    local _name _vers _conflicts
+
+    _conflicts="Conflicts:"
+    while read _name _vers; do
+       case "$_name" in ""| "#"*) continue ;; esac
+       _conflicts="$_conflicts $_name"
+       test -n "$_vers" && _conflicts="$_conflicts $_name (>= $vers)"
+       _conflicts="${_conflicts},"
+    done
+    echo "${_conflicts%,}"
+}
+
 pp_deb_make_control() {
     package_name=`pp_deb_cmp_full_name "$1"`
     cat <<-.
        Package: ${package_name}
-       Version: ${pp_deb_version:-$version}-${pp_deb_release:-1}
+       Version: `pp_deb_version_final`-${pp_deb_release:-1}
        Section: ${pp_deb_section:-contrib}
        Priority: optional
        Architecture: ${pp_deb_arch}
@@ -3682,6 +3949,9 @@ pp_deb_make_control() {
        sed -ne '/^[    ]*$/!s/^[       ]*/Depends: /p' \
            < $pp_wrkdir/%depend."$1"
     fi
+    if test -s $pp_wrkdir/%conflict."$1"; then
+       pp_deb_conflict < $pp_wrkdir/%conflict."$1"
+    fi
 }
 
 pp_deb_make_md5sums() {
@@ -3791,6 +4061,11 @@ pp_deb_make_DEBIAN() {
         "$pp_wrkdir/%preun.$cmp" "Pre-uninstall script for $cmp_full_name"\
         || exit $?
 
+    # Create postrm
+    pp_deb_make_package_maintainer_script "$data/DEBIAN/postrm" \
+        "$pp_wrkdir/%postun.$cmp" "Post-uninstall script for $cmp_full_name"\
+        || exit $?
+
     umask $old_umask
 }
 
@@ -3800,6 +4075,12 @@ pp_deb_make_data() {
     cmp=$1
     data=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
     cat $pp_wrkdir/%files.${cmp} | while read t m o g f p st; do
+       if test x"$m" = x"-"; then
+           case "$t" in
+               d) m=755;;
+               f) m=644;;
+           esac
+       fi
        test x"$o" = x"-" && o=root
        test x"$g" = x"-" && g=root
         case "$t" in
@@ -3897,7 +4178,7 @@ pp_backend_deb_cleanup () {
 
 pp_deb_name () {
     local cmp="${1:-run}"
-    echo `pp_deb_cmp_full_name $cmp`"_${pp_deb_version:-$version}-${pp_deb_release:-1}_${pp_deb_arch}.deb"
+    echo `pp_deb_cmp_full_name $cmp`"_"`pp_deb_version_final`"-${pp_deb_release:-1}_${pp_deb_arch}.deb"
 }
 pp_backend_deb_names () {
     for cmp in $pp_components
@@ -4072,17 +4353,11 @@ pp_backend_deb_vas_platforms () {
        *)      pp_die "unknown architecture ${pp_deb_arch_std}";;
     esac
 }
-pp_backend_deb_init_svc_vars () {
-    # Default multi-user runlevel on Debian is 2; 3-5 are also multi-user
-    pp_deb_default_start_runlevels="2 3 4 5"
-    pp_deb_default_svc_description="No description"
-}
-
 pp_backend_deb_init_svc_vars () {
 
     reload_signal=
-    start_runlevels=${pp_deb_default_start_runlevels}   # == lsb default-start
-    stop_runlevels="0 1 6"                              # == lsb default-stop
+    start_runlevels=${pp_deb_default_start_runlevels-"2 3 4 5"} # == lsb default-start
+    stop_runlevels=${pp_deb_default_stop_runlevels-"0 1 6"}     # == lsb default-stop
     svc_description="${pp_deb_default_svc_description}" # == lsb short descr
     svc_process=
 
@@ -4113,9 +4388,10 @@ pp_deb_service_make_init_script () {
     #_process=${svc_process:-"$1"} --? WTF
 
     #-- construct a start command that builds a pid file if needed
+    #-- the command name in /proc/[pid]/stat is limited to 15 characters 
     _cmd="$cmd";
     _cmd_path=`echo $cmd | cut -d" " -f1`
-    _cmd_name=`basename $_cmd_path`
+    _cmd_name=`basename $_cmd_path | cut -c1-15`
     _cmd_args=`echo $cmd | cut -d" " -f2-`
     test x"$_cmd_path" != x"$_cmd_args" || _cmd_args=
 
@@ -4128,7 +4404,7 @@ pp_deb_service_make_init_script () {
        # Required-Stop: ${lsb_required_stop}
        # Default-Start: ${start_runlevels}
        # Default-Stop: ${stop_runlevels}
-       # Short-Description: ${svc_description}
+       # Short-Description: ${svc_description:-no description}
        ### END INIT INFO
        # Generated by PolyPackage ${pp_version}
        # ${copyright}
@@ -4326,7 +4602,7 @@ esac
     chmod 755 $out
 }
 pp_backend_deb_function() {
-    case $1 in
+    case "$1" in
         pp_mkgroup) cat<<'.';;
            /usr/sbin/groupmod "$1" 2>/dev/null && return 0
             /usr/sbin/groupadd "$1"
@@ -4677,7 +4953,7 @@ cat <<-'.' >> $out
                return $rc
        }
 
-       case $1 in
+       case "$1" in
            start_msg) echo "Starting $svcs";;
        stop_msg)  echo "Stopping $svcs";;
        start)     pp_start;;
@@ -4743,7 +5019,7 @@ pp_kit_service_script () {
                    kill -0 "$pid" 2>/dev/null
                fi
            }
-           case $1 in
+           case "$1" in
                start_msg) echo "Starting the $svc service";;
                stop_msg)  echo "Stopping the $svc service";;
                start)
@@ -5096,28 +5372,29 @@ pp_rpm_detect_arch () {
     rm $pp_wrkdir/dummy.spec
 
     #-- Ask the kernel what machine architecture is in use
-    local arch=`uname -p`
-    if [ "$arch" = "unknown" ]; then
-       arch=`uname -m`
-    fi
-
-    case "$arch" in
-       i?86)   pp_rpm_arch_std=i386;;
-       x86_64) pp_rpm_arch_std=x86_64;;
-       ppc)    pp_rpm_arch_std=ppc;;
-       ppc64)  pp_rpm_arch_std=ppc64;;
-       ia64)   pp_rpm_arch_std=ia64;;
-       s390)   pp_rpm_arch_std=s390;;
-       s390x)  pp_rpm_arch_std=s390x;;
-       powerpc)
+    local arch
+    for arch in "`uname -m`" "`uname -p`"; do
+       case "$arch" in
+           i?86)
+               pp_rpm_arch_std=i386
+               break
+               ;;
+           x86_64|ppc|ppc64|ia64|s390|s390x)
+               pp_rpm_arch_std="$arch"
+               break
+               ;;
+           powerpc)
                # Probably AIX
                case "`/usr/sbin/lsattr -El proc0 -a type -F value`" in
                    PowerPC_POWER*)     pp_rpm_arch_std=ppc64;;
                    *)                  pp_rpm_arch_std=ppc;;
                esac
+               break
                ;;
-       *)      pp_rpm_arch_std=unknown;;
-    esac
+           *)  pp_rpm_arch_std=unknown
+               ;;
+       esac
+    done
 
     #-- Later on, when files are processed, we use 'file' to determine
     #   what platform ABIs are used. This is used when pp_rpm_arch == auto
@@ -5130,6 +5407,15 @@ pp_rpm_detect_distro () {
        pp_rpm_distro=`awk '
           /^White Box Enterprise Linux release/ { print "wbel" $6; exit; }
        ' /etc/whitebox-release`
+    elif test -f /etc/mandrakelinux-release; then
+       pp_rpm_distro=`awk '
+          /^Mandrakelinux release/ { print "mand" $3; exit; }
+       ' /etc/mandrake-release`
+    elif test -f /etc/mandrake-release; then
+       pp_rpm_distro=`awk '
+          /^Linux Mandrake release/ { print "mand" $4; exit; }
+          /^Mandrake Linux release/ { print "mand" $4; exit; }
+       ' /etc/mandrake-release`
     elif test -f /etc/fedora-release; then
        pp_rpm_distro=`awk '
           /^Fedora Core release/ { print "fc" $4; exit; }
@@ -5139,6 +5425,7 @@ pp_rpm_detect_distro () {
        pp_rpm_distro=`awk '
           /^Red Hat Enterprise Linux/ { print "rhel" $7; exit; }
           /^CentOS release/           { print "centos" $3; exit; }
+          /^CentOS Linux release/     { print "centos" $4; exit; }
           /^Red Hat Linux release/    { print "rh" $5; exit; }
        ' /etc/redhat-release`
     elif test -f /etc/SuSE-release; then
@@ -5150,6 +5437,10 @@ pp_rpm_detect_distro () {
           /^S[uU]SE LINUX Enterprise Server [0-9]/ { print "sles" $5; exit; }
           /^SuSE SLES-[0-9]/  { print "sles" substr($2,6); exit; }
        ' /etc/SuSE-release`
+    elif test -f /etc/pld-release; then
+       pp_rpm_distro=`awk '
+          /^[^ ]* PLD Linux/ { print "pld" $1; exit; }
+       ' /etc/pld-release`
     elif test X"`uname -s 2>/dev/null`" = X"AIX"; then
        local r v
        r=`uname -r`
@@ -5212,6 +5503,8 @@ pp_rpm_writefiles () {
                    farch=x86_64;;
                *": ELF 32-bit MSB "*", PowerPC"*)
                    farch=ppc;;
+               *": ELF 64-bit MSB "*", 64-bit PowerPC"*)
+                   farch=ppc64;;
                *": ELF 64-bit LSB "*", IA-64"*)
                    farch=ia64;;
                *": ELF 32-bit MSB "*", IBM S/390"*)
@@ -5221,10 +5514,34 @@ pp_rpm_writefiles () {
                *"executable (RISC System/6000)"*)
                    farch=ppc;;
                *"64-bit XCOFF executable"*)
-                   fatch=ppc64;;
+                   farch=ppc64;;
+               *" ELF "*)
+                   farch=ELF;;
                *)
                    farch=noarch;;
            esac
+           # If file(1) doesn't provide enough info, try readelf(1)
+           if test "$farch" = "ELF"; then
+               fo=`readelf -h "${pp_destdir}$p" | awk '{if ($1 == "Class:") {class=$2} else if ($1 == "Machine:") {machine=$0; sub(/^ *Machine: */, "", machine)}} END {print class " " machine}' 2>/dev/null`
+               case "$fo" in
+                   "ELF32 Intel 80386")
+                       farch=i386;;
+                   "ELF64 "*[xX]"86-64")
+                       farch=x86_64;;
+                   "ELF32 PowerPC")
+                       farch=ppc;;
+                   "ELF64 PowerPC"*)
+                       farch=ppc64;;
+                   "ELF64 IA-64")
+                       farch=ia64;;
+                   "ELF32 IBM S/390")
+                       farch=s390;;
+                   "ELF64 IBM S/390")
+                       farch=s390x;;
+                   *)
+                       farch=noarch;;
+               esac
+           fi
            pp_debug "file: $fo -> $farch"
            test x"$farch" = x"noarch" || pp_add_to_list pp_rpm_arch_seen $farch
        fi
@@ -5246,12 +5563,21 @@ pp_rpm_subname () {
 }
 
 pp_rpm_depend () {
+    local _name _vers
     while read _name _vers; do
         case "$_name" in ""| "#"*) continue ;; esac
         echo "Requires: $_name ${_vers:+>= $_vers}"
     done
 }
 
+pp_rpm_conflict () {
+    local _name _vers
+    while read _name _vers; do
+        case "$_name" in ""| "#"*) continue ;; esac
+        echo "Conflicts: $_name ${_vers:+>= $_vers}"
+    done
+}
+
 pp_rpm_override_requires () {
     local orig_find_requires
 
@@ -5317,6 +5643,9 @@ pp_backend_rpm () {
         elif test -s $pp_wrkdir/%depend.run; then
             pp_rpm_depend < $pp_wrkdir/%depend.run >> $specfile
         fi
+        if test -s $pp_wrkdir/%conflict.run; then
+            pp_rpm_conflict < $pp_wrkdir/%conflict.run >> $specfile
+        fi
 
        pp_rpm_override_requires >> $specfile
 
@@ -5356,6 +5685,9 @@ pp_backend_rpm () {
                 elif test -s $pp_wrkdir/%depend.$cmp; then
                     pp_rpm_depend < $pp_wrkdir/%depend.$cmp >> $specfile
                 fi
+                if test -s $pp_wrkdir/%conflict.$cmp; then
+                    pp_rpm_conflict < $pp_wrkdir/%conflict.$cmp >> $specfile
+                fi
 
                 eval '_pkg="$pp_rpm_'$cmp'_provides"'
                eval pp_rpm_label Provides $_pkg
@@ -5442,6 +5774,13 @@ pp_backend_rpm () {
                 cat $pp_wrkdir/%preun.$cmp
                 echo :   # causes script to exit true
             fi
+
+            if test -s $pp_wrkdir/%postun.$cmp; then
+                echo ""
+                echo "%postun $_subname"
+                cat $pp_wrkdir/%postun.$cmp
+                echo :   # causes script to exit true
+            fi
        done >>$specfile
 
         #-- create a suitable work area for rpmbuild
@@ -5675,11 +6014,6 @@ pp_backend_rpm_vas_platforms () {
     esac
 }
 
-pp_backend_rpm_init_svc_vars () {
-    pp_rpm_default_start_runlevels="2 3 4 5"
-    pp_rpm_default_svc_description="No description"
-}
-
 pp_rpm_service_install_common () {
     cat <<-'.'
 
@@ -5786,8 +6120,8 @@ pp_rpm_service_remove () {
 pp_backend_rpm_init_svc_vars () {
 
     reload_signal=
-    start_runlevels=${pp_rpm_default_start_runlevels}   # == lsb default-start
-    stop_runlevels="0 1 6"                              # == lsb default-stop
+    start_runlevels=${pp_rpm_default_start_runlevels-"2 3 4 5"} # == lsb default-start
+    stop_runlevels=${pp_rpm_default_stop_runlevels-"0 1 6"} # == lsb default-stop
     svc_description="${pp_rpm_default_svc_description}" # == lsb short descr
     svc_process=
 
@@ -6084,7 +6418,7 @@ pp_rpm_service_make_init_script () {
     chmod 755 $out
 }
 pp_backend_rpm_function () {
-    case $1 in
+    case "$1" in
         pp_mkgroup) cat<<'.';;
             /usr/sbin/groupadd -f -r "$1"
 .
@@ -6195,7 +6529,7 @@ pp_backend_rpm_function () {
     Examples found in /System/Library/LaunchDaemons/
     See manual page launchd.plist(5) for details:
 
-    { Label: "com.quest.vintela.foo",                        # required
+    { Label: "com.quest.rc.foo",                        # required
       Program: "/sbin/program",
       ProgramArguments: [ "/sbin/program", "arg1", "arg2" ], # required
       RunAtLoad: true,
@@ -6241,9 +6575,13 @@ pp_backend_macos_init () {
     pp_macos_bundle_vendor=
     pp_macos_bundle_version=
     pp_macos_bundle_info_string=
-    pp_macos_prog_packagemaker=/Developer/usr/bin/packagemaker
-    pp_macos_pkg_domain=anywhere
-    pp_macos_pkg_extra_flags=
+    pp_macos_pkg_type=bundle
+    pp_macos_pkg_license=
+    pp_macos_pkg_readme=
+    pp_macos_pkg_welcome=
+    pp_macos_sudo=sudo
+    # OS X puts the library version *before* the .dylib extension
+    pp_shlib_suffix='*.dylib'
 }
 
 pp_macos_plist () {
@@ -6282,65 +6620,132 @@ pp_macos_plist () {
 pp_macos_rewrite_cpio () {
     typeset script
     script=$pp_wrkdir/cpio-rewrite.pl
-    # rely on the fact that OS X comes with perl. It is a little easier to
-    # re-write a binary stream with perl than it is with posix :)
-    #
-    # A CPIO header block has octal fields at the following offset/lengths:
-    #   0  6 magic
-    #   6  6 dev
-    #  12  6 ino
-    #  18  6 mode
-    #  24  6 uid
-    #  30  6 gid
-    #  36  6 nlink
-    #  42  6 rdev
-    #  48 11 mtime
-    #  59  6 namesize
-    #  65 11 filesize
-    #  76    --
     cat <<-'.' >$script
+       #!/usr/bin/perl
+       #
+       # Filter a cpio file, applying the user/group/mode specified in %files
+       #
+       # A CPIO header block has octal fields at the following offset/lengths:
+       #   0  6 magic
+       #   6  6 dev
+       #  12  6 ino
+       #  18  6 mode
+       #  24  6 uid
+       #  30  6 gid
+       #  36  6 nlink
+       #  42  6 rdev
+       #  48 11 mtime
+       #  59  6 namesize (including NUL terminator)
+       #  65 11 filesize
+       #  76    --
+       #
+       use strict;
+       use warnings;
+       no strict 'subs';
+
+       # set %uid, %gid, %mode based on %files
+       my (%uid, %gid, %mode, %users, %groups);
+       my %type_map = ( d => 0040000, f => 0100000, s => 0120000 );
        while (<DATA>) {
-               my ($type,$mode,$uid,$gid,$flags,$name) =
-                   m/^(.) (\d+) (\S+) (\S+) (\S+) (.*)/;
-               $uid = 0 if $uid eq "-";
-               $gid = 0 if $gid eq "-";
-               if ($uid ne "=" and $uid =~ m/\D/) {
-                       my @pw = getpwnam($uid) or die "bad username '$uid'";
-                       $uid = $pw[2];
-               }
-               if ($gid ne "=" and $gid =~ m/\D/) {
-                       my @gr = getgrnam($gid) or die "bad group '$gid'";
-                       $gid = $gr[2];
-               }
-               $name = ".".$name."\0";
-               $ok{$name} = 1;
-               $uid{$name} = sprintf("%06o",int($uid)) unless $uid eq "=";
-               $gid{$name} = sprintf("%06o",int($gid)) unless $gid eq "=";
-               $mode{$name} = sprintf("%06o",oct($mode)) unless $mode eq "=";
+           my ($type,$mode,$uid,$gid,$flags,$name) =
+               m/^(.) (\S+) (\S+) (\S+) (\S+) (\S+)/;
+           $mode = $type eq "f" ? "0644" : "0755" if $mode eq "-";
+           $uid = 0 if $uid eq "-";
+           $gid = 0 if $gid eq "-";
+           if ($uid ne "=" and $uid =~ m/\D/) {
+               unless (exists $users{$uid}) {
+                   my @pw = getpwnam($uid) or die "bad username '$uid'";
+                   $users{$uid} = $pw[2];
+               }
+               $uid = $users{$uid};
+           }
+           if ($gid ne "=" and $gid =~ m/\D/) {
+               unless (exists $groups{$gid}) {
+                   my @gr = getgrnam($gid) or die "bad group'$gid'";
+                   $groups{$gid} = $gr[2];
+               }
+               $gid = $groups{$gid};
+           }
+           $name =~ s:/$:: if $type eq "d";
+           $name = ".".$name."\0";
+           $uid{$name} = sprintf("%06o",int($uid)) unless $uid eq "=";
+           $gid{$name} = sprintf("%06o",int($gid)) unless $gid eq "=";
+           $mode{$name} = sprintf("%06o",oct($mode)|$type_map{$type}) unless $mode eq "=";
        }
-       $ok{"TRAILER!!!\0"} = 1;
-       while (!eof STDIN) {
-               read STDIN, $header, 76;
-               die "bad magic" unless $header =~ m/^070707/;
-               $namesize = oct(substr($header,59,6));
-               $filesize = oct(substr($header,65,11));
-               read STDIN, $name, $namesize;
-               # convert uid and gid to 0
-               substr($header, 24, 6) = $uid{$name} if defined($uid{$name});
-               substr($header, 30, 6) = $gid{$name} if defined($gid{$name});
-               substr($header, 18, 6) = $mode{$name} if defined($mode{$name});
-               print ($header, $name) if $ok{$name};
-               # copy-through the file data
-               while ($filesize > 0) {
-                       my $seg = 8192;
-                       $seg = $filesize if $filesize < $seg;
-                       undef $data;
-                       read STDIN, $data, $seg;
-                       print $data if $ok{$name};
-                       $filesize -= $seg;
-               }
+       undef %users;
+       undef %groups;
+       # parse the cpio file
+       my $hdrlen = 76;
+       while (read(STDIN, my $header, $hdrlen)) {
+           my ($name, $namesize, $filesize);
+           my $filepad = 0;
+           if ($header =~ m/^07070[12]/) {
+               # SVR4 ASCII format, convert to ODC
+               if ($hdrlen == 76) {
+                   # Read in rest of header and update header len for SVR4
+                   read(STDIN, $header, 110 - 76, 76);
+                   $hdrlen = 110;
+               }
+               my $ino = hex(substr($header, 6, 8)) & 0x3ffff;
+               my $mode = hex(substr($header, 14, 8)) & 0x3ffff;
+               my $uid = hex(substr($header, 22, 8)) & 0x3ffff;
+               my $gid = hex(substr($header, 30, 8)) & 0x3ffff;
+               my $nlink = hex(substr($header, 38, 8)) & 0x3ffff;
+               my $mtime = hex(substr($header, 46, 8)) & 0xffffffff;
+               $filesize = hex(substr($header, 54, 8)) & 0xffffffff;
+               my $dev_maj = hex(substr($header, 62, 8));
+               my $dev_min = hex(substr($header, 70, 8));
+               my $dev = &makedev($dev_maj, $dev_min) & 0x3ffff;
+               my $rdev_maj = hex(substr($header, 78, 8));
+               my $rdev_min = hex(substr($header, 86, 8));
+               my $rdev = &makedev($rdev_maj, $rdev_min) & 0x3ffff;
+               $namesize = hex(substr($header, 94, 8)) & 0x3ffff;
+               read(STDIN, $name, $namesize);
+               # Header + name is padded to a multiple of 4 bytes
+               my $namepad = (($hdrlen + $namesize + 3) & 0xfffffffc) - ($hdrlen + $namesize);
+               read(STDIN, my $padding, $namepad) if ($namepad);
+               # File data is padded to be a multiple of 4 bytes
+               $filepad = (($filesize + 3) & 0xfffffffc) - $filesize;
+
+               my $new_header = sprintf("070707%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o", $dev, $ino, $mode, $uid, $gid, $nlink, $rdev, $mtime, $namesize, $filesize);
+               $header = $new_header;
+           } elsif ($header =~ m/^070707/) {
+               # POSIX Portable ASCII Format
+               $namesize = oct(substr($header, 59, 6));
+               $filesize = oct(substr($header, 65, 11));
+               read(STDIN, $name, $namesize);
+           } else {
+               die "bad magic";
+           }
+           # update uid, gid and mode (already in octal)
+           substr($header, 24, 6) = $uid{$name} if exists $uid{$name};
+           substr($header, 30, 6) = $gid{$name} if exists $gid{$name};
+           substr($header, 18, 6) = $mode{$name} if exists $mode{$name};
+           print($header, $name);
+           # check for trailer at EOF
+           last if $filesize == 0 && $name =~ /^TRAILER!!!\0/;
+           # copy-through the file data
+           while ($filesize > 0) {
+               my $seg = 8192;
+               $seg = $filesize if $filesize < $seg;
+               read(STDIN, my $data, $seg);
+               print $data;
+               $filesize -= $seg;
+           }
+           # If file data is padded, skip it
+           read(STDIN, my $padding, $filepad) if ($filepad);
+       }
+       # pass through any padding at the end (blocksize-dependent)
+       for (;;) {
+           my $numread = read(STDIN, my $data, 8192);
+           last unless $numread;
+           print $data;
        }
        exit(0);
+
+       sub makedev {
+           (((($_[0] & 0xff)) << 24) | ($_[1] & 0xffffff));
+       }
        __DATA__
 .
     # Append to the script the %files data
@@ -6356,7 +6761,7 @@ pp_macos_files_bom () {
            ?) m="000$m";;
            ??) m="00$m";;
            ???) m="0$m";;
-           ?????*) pp_fatal "pp_macos_writebom: mode '$m' too long";;
+           ?????*) pp_error "pp_macos_writebom: mode '$m' too long";;
        esac
 
        # convert owner,group into owner/group in octal
@@ -6366,19 +6771,25 @@ pp_macos_files_bom () {
 
        case $t in
            f)
+               test x"$m" = x"000-" && m=0644
                echo ".$p       10$m    $owner  `
                    /usr/bin/cksum < "${pp_destdir}$p" |
-                   awk '{print $2 "    " $1}'`";;
+                   awk '{print $2 "    " $1}'`"
+               ;;
            d)
-               echo ".${p%/}   4$m     $owner";;
+               test x"$m" = x"000-" && m=0755
+               echo ".${p%/}   4$m     $owner"
+               ;;
            s)
+               test x"$m" = x"000-" && m=0755
                rl=`/usr/bin/readlink "${pp_destdir}$p"`
                #test x"$rl" = x"$st" ||
                #    pp_error "symlink mismatch $rl != $st"
                echo ".$p       12$m    $owner  `
                    /usr/bin/readlink -n "${pp_destdir}$p" |
                    /usr/bin/cksum |
-                   awk '{print $2 "    " $1}'` $st";;
+                   awk '{print $2 "    " $1}'` $st"
+               ;;
        esac
     done
 }
@@ -6392,8 +6803,11 @@ pp_macos_bom_fix_parents () {
                      print "$d\t40755\t0/0\n";
                  }
                }
-       m/^\S+/;
-       &chk(&dirname($&));'
+       m/^(\S+)\s+(\d+)/;
+       if (oct($2) & 040000) {
+           $seen{$1}++; # directory
+       }
+       &chk(&dirname($1));'
 }
 
 pp_macos_files_size () {
@@ -6434,28 +6848,38 @@ pp_macos_mkbom () {
     pp_warn "mkbom workaround: copying source files to staging area"
 
     bomstage=$pp_wrkdir/bom_stage
+    $pp_macos_sudo /bin/mkdir "$bomstage"
     while IFS='        ' read path mode ugid size cksumi linkpath; do
        if test -h "$pp_destdir/$path"; then
-           /bin/ln -s "$linkpath" "$bomstage/$path"
+           $pp_macos_sudo /bin/ln -s "$linkpath" "$bomstage/$path"
        else
            if test -d "$pp_destdir/$path"; then
-               /bin/mkdir -p "$bomstage/$path"
+               $pp_macos_sudo /bin/mkdir -p "$bomstage/$path"
            else
-               /bin/cp "$pp_destdir/$path" "$bomstage/$path"
+               $pp_macos_sudo /bin/cp "$pp_destdir/$path" "$bomstage/$path"
            fi
-           /bin/chmod $mode "$bomstage/$path"
-           /usr/sbin/chown `echo $ugid| tr / :` "$bomstage/$path"
+           $pp_macos_sudo /bin/chmod $mode "$bomstage/$path"
+           $pp_macos_sudo /usr/sbin/chown `echo $ugid| tr / :` "$bomstage/$path"
        fi
     done <"$1"
-    (cd $bomstage && mkbom . $pp_wrkdir/bom_stage.bom) ||
+    (cd $bomstage && $pp_macos_sudo mkbom . $pp_wrkdir/bom_stage.bom) ||
        pp_error "mkbom failed"
-    mv $pp_wrkdir/bom_stage.bom "$2"
+    $pp_macos_sudo mv $pp_wrkdir/bom_stage.bom "$2"
 }
 
 pp_backend_macos () {
-    typeset pkgdir Contents Resources lprojdir
+    : ${pp_macos_bundle_id:=$pp_macos_default_bundle_id_prefix$name}
+    case "$pp_macos_pkg_type" in
+       bundle) pp_backend_macos_bundle;;
+       flat) pp_backend_macos_flat;;
+       *) pp_error "unsupported package type $pp_macos_pkg_type";;
+    esac
+}
+
+pp_backend_macos_bundle () {
+    typeset pkgdir Contents Resources lprojdir svc
     typeset Info_plist Description_plist
-    typeset bundle_vendor bundle_version size
+    typeset bundle_vendor bundle_version size cmp filelists
 
     mac_version=`sw_vers -productVersion`
     bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
@@ -6463,9 +6887,6 @@ pp_backend_macos () {
     if test -z "$pp_macos_bundle_version"; then
         bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
             -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
-        #if test x"$bundle_version" != x"$version"; then
-        #    pp_warn "converted version from '$version' to '$bundle_version'"
-        #fi
     else
         bundle_version="$pp_macos_bundle_version"
     fi
@@ -6477,7 +6898,7 @@ pp_backend_macos () {
     Resources=$Contents/Resources
     lprojdir=$Resources/en.lproj
     mkdir $pkgdir $Contents $Resources $lprojdir ||
-       pp_fatal "Can't make package temporary directories"
+       pp_error "Can't make package temporary directories"
 
     echo "major: 1" > $Resources/package_version
     echo "minor: 0" >> $Resources/package_version
@@ -6485,12 +6906,56 @@ pp_backend_macos () {
     case $mac_version in
         "10.6"*)
             xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/package_version"
-            xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/PkgInfo"
+            xattr -w "com.apple.TextEncoding" "macintosh;0" "$Contents/PkgInfo"
             ;;
     esac
 
+    # Copy welcome file/dir for display at package install time.
+    if test -n "$pp_macos_pkg_welcome"; then
+       typeset sfx
+       sfx=`echo "$pp_macos_pkg_welcome"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+       case "$sfx" in
+           rtf|html|rtfd|txt) ;;
+           *) sfx=txt;;
+       esac
+       cp -R ${pp_macos_pkg_welcome} $Resources/Welcome.$sfx
+    fi
+
+    # Copy readme file/dir for display at package install time.
+    if test -n "$pp_macos_pkg_readme"; then
+       typeset sfx
+       sfx=`echo "$pp_macos_pkg_readme"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+       case "$sfx" in
+           rtf|html|rtfd|txt) ;;
+           *) sfx=txt;;
+       esac
+       cp -R ${pp_macos_pkg_readme} $Resources/ReadMe.$sfx
+    fi
+
+    # Copy license file/dir for display at package install time.
+    if test -n "$pp_macos_pkg_license"; then
+       typeset sfx
+       sfx=`echo "$pp_macos_pkg_license"|sed 's/^.*\.\([^\.]*\)$/\1/'`
+       case "$sfx" in
+           rtf|html|rtfd|txt) ;;
+           *) sfx=txt;;
+       esac
+       cp -R ${pp_macos_pkg_license} $Resources/License.$sfx
+    fi
+
+    # Add services (may modify %files)
+    for svc in $pp_services .; do
+       test . = "$svc" && continue
+       pp_macos_add_service $svc
+    done
+
+    # Find file lists (%files.* includes ignore files)
+    for cmp in $pp_components; do
+       test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
+    done
+
     # compute the installed size
-    size=`cat $pp_wrkdir/%files.* | pp_macos_files_size`
+    size=`cat $filelists | pp_macos_files_size`
 
     #-- Create Info.plist
     Info_plist=$Contents/Info.plist
@@ -6499,7 +6964,7 @@ pp_backend_macos () {
        key CFBundleGetInfoString string \
            "${pp_macos_bundle_info_string:-$version $bundle_vendor}" \
        key CFBundleIdentifier string \
-           "${pp_macos_bundle_id:-$pp_macos_default_bundle_id_prefix$name}" \
+           "${pp_macos_bundle_id}" \
     key CFBundleName string "$name" \
        key CFBundleShortVersionString string "$bundle_version" \
        key IFMajorVersion integer 1 \
@@ -6531,8 +6996,8 @@ pp_backend_macos () {
            key IFPkgDescriptionVersion string "$version" \
        \} end-plist > $Description_plist
 
-       # write Resources/files
-    cat $pp_wrkdir/%files.* | awk '{print $6}' > $Resources/files
+    # write Resources/files
+    awk '{print $6}' $filelists > $Resources/files
 
     # write package size file
     printf \
@@ -6541,7 +7006,7 @@ InstalledSize $size
 CompressedSize 0
 " > $Resources/$name.sizes
 
-    # write Resources/postinstall
+    # write Resources/preinstall
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%pre.$cmp; then
            if test ! -s $Resources/preinstall; then
@@ -6565,7 +7030,7 @@ CompressedSize 0
        fi
     done
 
-    # write Resources/postupgrade)
+    # write Resources/postupgrade
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%postup.$cmp; then
            if test ! -s $Resources/postupgrade; then
@@ -6577,7 +7042,7 @@ CompressedSize 0
        fi
     done
 
-    # write Resources/preremove)
+    # write Resources/preremove
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%preun.$cmp; then
            if test ! -s $Resources/preremove; then
@@ -6589,7 +7054,7 @@ CompressedSize 0
        fi
     done
 
-    # write Resources/postremove)
+    # write Resources/postremove
     for cmp in $pp_components; do
        if test -s $pp_wrkdir/%postun.$cmp; then
            if test ! -s $Resources/postremove; then
@@ -6607,20 +7072,199 @@ CompressedSize 0
         echo "requires=$pp_macos_requires" >> $Resources/uninstall
     fi
 
+    . $pp_wrkdir/%fixup
+
     # Create the bill-of-materials (Archive.bom)
-    cat $pp_wrkdir/%files.* | pp_macos_files_bom | sort |
+    cat $filelists | pp_macos_files_bom | sort |
        pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
 
     pp_macos_mkbom $pp_wrkdir/tmp.bomls $Contents/Archive.bom
 
     # Create the cpio archive (Archive.pax.gz)
-    # On 10.5, we used "-f -" to write explicitly to stdout
     (
     cd $pp_destdir &&
-    cat $pp_wrkdir/%files.* | awk '{ print "." $6 }' | sed '/\/$/d' | sort | /bin/pax -w -f - | gzip -9 -c > $Contents/Archive.pax.gz
+    awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $Contents/Archive.pax.gz
+    )
+
+    test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
+
+    rm -f ${name}-${version}.dmg
+    hdiutil create -fs HFS+ -srcfolder $pkgdir -volname $name ${name}-${version}.dmg
+}
+
+pp_backend_macos_flat () {
+    typeset pkgdir bundledir Resources lprojdir svc
+    typeset Info_plist Description_plist
+    typeset bundle_vendor bundle_version size numfiles cmp filelists
+
+    mac_version=`sw_vers -productVersion`
+    bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
+
+    if test -z "$pp_macos_bundle_version"; then
+        bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
+            -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
+    else
+        bundle_version="$pp_macos_bundle_version"
+    fi
+    source_version=`echo $version | sed 's/.*\.//'`
+
+    # build the flat package layout
+    pkgdir=$pp_wrkdir/pkg
+    bundledir=$pp_wrkdir/pkg/$name.pkg
+    Resources=$pkgdir/Resources
+    lprojdir=$Resources/en.lproj
+    mkdir $pkgdir $bundledir $Resources $lprojdir ||
+       pp_error "Can't make package temporary directories"
+
+    # Add services (may modify %files)
+    for svc in $pp_services .; do
+       test . = "$svc" && continue
+       pp_macos_add_service $svc
+    done
+
+    # Find file lists (%files.* includes ignore files)
+    for cmp in $pp_components; do
+       test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
+    done
+
+    # compute the installed size and number of files/dirs
+    size=`cat $filelists | pp_macos_files_size`
+    numfiles=`cat $filelists | wc -l`
+    numfiles="${numfiles##* }"
+
+    # Write Distribution file
+    cat <<-. >$pkgdir/Distribution
+       <?xml version="1.0" encoding="UTF-8"?>
+       <installer-script minSpecVersion="1.000000" authoringTool="com.quest.rc.PolyPkg" authoringToolVersion="$pp_version" authoringToolBuild="$pp_revision">
+           <title>$name $version</title>
+           <options customize="never" allow-external-scripts="no"/>
+           <domains enable_localSystem="true"/>
+.
+    if test -n "$pp_macos_pkg_welcome"; then
+       cp -R "${pp_macos_pkg_welcome}" $Resources
+       echo "    <welcome file=\"${pp_macos_pkg_welcome##*/}\"/>" >>$pkgdir/Distribution
+    fi
+    if test -n "$pp_macos_pkg_readme"; then
+       cp -R "${pp_macos_pkg_readme}" $Resources
+       echo "    <readme file=\"${pp_macos_pkg_readme##*/}\"/>" >>$pkgdir/Distribution
+    fi
+    if test -n "$pp_macos_pkg_license"; then
+       cp -R "${pp_macos_pkg_license}" $Resources
+       echo "    <license file=\"${pp_macos_pkg_license##*/}\"/>" >>$pkgdir/Distribution
+    fi
+    cat <<-. >>$pkgdir/Distribution
+           <choices-outline>
+               <line choice="choice0"/>
+           </choices-outline>
+           <choice id="choice0" title="$name $version">
+               <pkg-ref id="${pp_macos_bundle_id}"/>
+           </choice>
+           <pkg-ref id="${pp_macos_bundle_id}" installKBytes="$size" version="$version" auth="Root">#$name.pkg</pkg-ref>
+       </installer-script>
+.
+
+    # write scripts archive
+    # XXX - missing preupgrade, preflight, postflight
+    mkdir $pp_wrkdir/scripts
+    for cmp in $pp_components; do
+       if test -s $pp_wrkdir/%pre.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/preinstall; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/preinstall
+               chmod +x $pp_wrkdir/scripts/preinstall
+           fi
+           cat $pp_wrkdir/%pre.$cmp >> $pp_wrkdir/scripts/preinstall
+           echo : >> $pp_wrkdir/scripts/preinstall
+       fi
+       if test -s $pp_wrkdir/%post.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/postinstall; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/postinstall
+               chmod +x $pp_wrkdir/scripts/postinstall
+           fi
+           cat $pp_wrkdir/%post.$cmp >> $pp_wrkdir/scripts/postinstall
+           echo : >> $pp_wrkdir/scripts/postinstall
+       fi
+       if test -s $pp_wrkdir/%postup.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/postupgrade; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/postupgrade
+               chmod +x $pp_wrkdir/scripts/postupgrade
+           fi
+           cat $pp_wrkdir/%postup.$cmp >> $pp_wrkdir/scripts/postupgrade
+           echo : >> $pp_wrkdir/scripts/postupgrade
+       fi
+       # XXX - not supported
+       if test -s $pp_wrkdir/%preun.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/preremove; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/preremove
+               chmod +x $pp_wrkdir/scripts/preremove
+           fi
+           cat $pp_wrkdir/%preun.$cmp >> $pp_wrkdir/scripts/preremove
+           echo : >> $pp_wrkdir/scripts/preremove
+       fi
+       # XXX - not supported
+       if test -s $pp_wrkdir/%postun.$cmp; then
+           if test ! -s $pp_wrkdir/scripts/postremove; then
+               echo "#!/bin/sh" > $pp_wrkdir/scripts/postremove
+               chmod +x $pp_wrkdir/scripts/postremove
+           fi
+           cat $pp_wrkdir/%postun.$cmp >> $pp_wrkdir/scripts/postremove
+           echo : >> $pp_wrkdir/scripts/postremove
+       fi
+    done
+    if test "`echo $pp_wrkdir/scripts/*`" != "$pp_wrkdir/scripts/*"; then
+       # write scripts archive, scripts are mode 0755 uid/gid 0/0
+       # resetting the owner and mode is not strictly required
+       (
+       cd $pp_wrkdir/scripts || pp_error "Can't cd to $pp_wrkdir/scripts"
+       rm -f $pp_wrkdir/tmp.files.scripts
+       for s in *; do
+           echo "f 0755 0 0 - ./$s" >>$pp_wrkdir/tmp.files.scripts
+       done
+       find . -type f | /usr/bin/cpio -o | pp_macos_rewrite_cpio $pp_wrkdir/tmp.files.scripts | gzip -9f -c > $bundledir/Scripts
+       )
+    fi
+
+    # Write PackageInfo file
+    cat <<-. >$bundledir/PackageInfo
+       <?xml version="1.0" encoding="UTF-8"?>
+       <pkg-info format-version="2" identifier="${pp_macos_bundle_id}" version="$version" install-location="/" relocatable="false" overwrite-permissions="true" followSymLinks="true" auth="root">
+           <payload installKBytes="$size" numberOfFiles="$numfiles"/>
+.
+    if test -s $bundledir/Scripts; then
+       echo "    <scripts>" >>$bundledir/PackageInfo
+       for s in preflight postflight preinstall postinstall preupgrade postupgrade; do
+           if test -s "$pp_wrkdir/scripts/$s"; then
+               echo "  <$s file=\"$s\"/>" >>$bundledir/PackageInfo
+           fi
+       done
+       echo "    </scripts>" >>$bundledir/PackageInfo
+    fi
+    cat <<-. >>$bundledir/PackageInfo
+       </pkg-info>
+.
+
+    . $pp_wrkdir/%fixup
+
+    # Create the bill-of-materials (Bom)
+    cat $filelists | pp_macos_files_bom | sort |
+       pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
+    pp_macos_mkbom $pp_wrkdir/tmp.bomls $bundledir/Bom
+
+    # Create the cpio payload
+    (
+    cd $pp_destdir || pp_error "Can't cd to $pp_destdir"
+    awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $bundledir/Payload
     )
 
-       rm -rf $pp_wrkdir/bom_stage
+    test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
+
+    # Create the flat package with xar (like pkgutil --flatten does)
+    # Note that --distribution is only supported by Mac OS X 10.6 and above
+    xar_flags="--compression=bzip2 --no-compress Scripts --no-compress Payload"
+    case $mac_version in
+        "10.5"*) ;;
+       *)       xar_flags="$xar_flags --distribution";;
+    esac
+    (cd $pkgdir && /usr/bin/xar $xar_flags -cf "../$name-$version.pkg" *)
 }
 
 pp_backend_macos_cleanup () {
@@ -6628,7 +7272,11 @@ pp_backend_macos_cleanup () {
 }
 
 pp_backend_macos_names () {
-    echo ${name}.pkg
+    case "$pp_macos_pkg_type" in
+       bundle) echo ${name}.pkg;;
+       flat) echo ${name}-${version}.pkg;;
+       *) pp_error "unsupported package type $pp_macos_pkg_type";;
+    esac
 }
 
 pp_backend_macos_install_script () {
@@ -6692,7 +7340,106 @@ pp_backend_macos_install_script () {
 }
 
 pp_backend_macos_init_svc_vars () {
-    :
+    pp_macos_start_services_after_install=false
+    pp_macos_service_name=
+    pp_macos_default_service_id_prefix="com.quest.rc."
+    pp_macos_service_id=
+    pp_macos_service_user=
+    pp_macos_service_group=
+    pp_macos_service_initgroups=
+    pp_macos_service_umask=
+    pp_macos_service_cwd=
+    pp_macos_service_nice=
+    pp_macos_svc_plist_file=
+}
+
+pp_macos_launchd_plist () {
+    typeset svc svc_id
+
+    svc="$1"
+    svc_id="$2"
+
+    set -- $cmd
+
+    if [ -n "$pp_macos_svc_plist_file" ]; then
+        echo "## Launchd plist file already defined at $pp_macos_svc_plist_file"
+        return
+    fi
+
+    echo "## Generating the launchd plist file for $svc"
+    pp_macos_svc_plist_file="$pp_wrkdir/$svc.plist"
+    cat <<-. > $pp_macos_svc_plist_file
+       <?xml version="1.0" encoding="UTF-8"?>
+       <!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
+       http://www.apple.com/DTDs/PropertyList-1.0.dtd >
+       <plist version="1.0">
+       <dict>
+           <key>Label</key>
+           <string>$svc_id</string>
+           <key>ProgramArguments</key>
+           <array>
+.
+    while test $# != 0; do
+       printf "        <string>$1</string>\n" >> $pp_macos_svc_plist_file
+       shift
+    done
+    cat <<-. >> $pp_macos_svc_plist_file
+           </array>
+           <key>KeepAlive</key>
+           <true/>
+.
+    if test -n "$pp_macos_service_user"; then
+       printf "    <key>UserName</key>\n" >> $pp_macos_svc_plist_file
+       printf "    <string>$pp_macos_service_user</string>\n" >> $pp_macos_svc_plist_file
+    fi
+    if test -n "$pp_macos_service_group"; then
+       printf "    <key>GroupName</key>\n" >> $pp_macos_svc_plist_file
+       printf "    <string>$pp_macos_service_group</string>\n" >> $pp_macos_svc_plist_file
+    fi
+    if test -n "$pp_macos_service_initgroups"; then
+       printf "    <key>InitGroups</key>\n" >> $pp_macos_svc_plist_file
+       printf "    <string>$pp_macos_service_initgroups</string>\n" >> $pp_macos_svc_plist_file
+    fi
+    if test -n "$pp_macos_service_umask"; then
+       printf "    <key>Umask</key>\n" >> $pp_macos_svc_plist_file
+       printf "    <string>$pp_macos_service_umask</string>\n" >> $pp_macos_svc_plist_file
+    fi
+    if test -n "$pp_macos_service_cwd"; then
+       printf "    <key>WorkingDirectory</key>\n" >> $pp_macos_svc_plist_file
+       printf "    <string>$pp_macos_service_cwd</string>\n" >> $pp_macos_svc_plist_file
+    fi
+    if test -n "$pp_macos_service_nice"; then
+       printf "    <key>Nice</key>\n" >> $pp_macos_svc_plist_file
+       printf "    <string>$pp_macos_service_nice</string>\n" >> $pp_macos_svc_plist_file
+    fi
+    cat <<-. >> $pp_macos_svc_plist_file
+       </dict>
+       </plist>
+.
+}
+
+pp_macos_add_service () {
+    typeset svc svc_id plist_file plist_dir
+
+    pp_load_service_vars "$1"
+    svc=${pp_macos_service_name:-$1}
+    svc_id=${pp_macos_service_id:-$pp_macos_default_service_id_prefix$svc}
+
+    #-- create a plist file for svc
+    pp_macos_launchd_plist "$svc" "$svc_id"
+
+    #-- copy the plist file into place and add to %files
+    plist_dir="/Library/LaunchDaemons"
+    plist_file="$plist_dir/$svc_id.plist"
+    mkdir -p "$pp_destdir/$plist_dir"
+    cp "$pp_macos_svc_plist_file" "$pp_destdir/$plist_file"
+    pp_add_file_if_missing "$plist_file"
+
+    #-- add code to start the service on install
+    ${pp_macos_start_services_after_install} && <<-. >> $pp_wrkdir/%post.$svc
+       # start service '$svc' automatically after install
+       launchctl load "$plist_file"
+.
 }
 
 pp_backend_macos_probe () {
@@ -6710,7 +7457,7 @@ pp_backend_macos_vas_platforms () {
     echo "osx"    # XXX non-really sure what they do.. it should be "macos"
 }
 pp_backend_macos_function () {
-    case $1 in
+    case "$1" in
        _pp_macos_search_unused) cat<<'.';;
            # Find an unused value in the given path
            # args: path attribute minid [maxid]