1#!/bin/sh
2# Copyright 2012 Quest Software, Inc. ALL RIGHTS RESERVED
3pp_revision="371"
4 # Copyright 2012 Quest Software, Inc.  ALL RIGHTS RESERVED.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 # 3. Neither the name of Quest Software, Inc. nor the names of its
16 #    contributors may be used to endorse or promote products derived from
17 #    this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25 # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 # Please see <http://rc.quest.com/topics/polypkg/> for more information
32
33pp_version="1.0.0.$pp_revision"
34pp_copyright="Copyright 2012, Quest Software, Inc. ALL RIGHTS RESERVED."
35
36pp_opt_debug=false
37pp_opt_destdir="$DESTDIR"
38pp_opt_install_script=
39pp_opt_list=false
40pp_opt_no_clean=false
41pp_opt_no_package=false
42pp_opt_only_front=false
43pp_opt_platform=
44pp_opt_probe=false
45pp_opt_strip=false
46pp_opt_save_unstripped=false
47pp_opt_vas_platforms=false
48pp_opt_wrkdir="`pwd`/pp.work.$$"
49pp_opt_verbose=false
50pp_opt_version=false
51pp_opt_input="-"
52pp_opt_init_vars=""
53pp_opt_eval=
54
55test -n "$PP_NO_CLEAN" && pp_opt_no_clean=true
56test -n "$PP_DEBUG" && pp_opt_debug=true
57test -n "$PP_VERBOSE" && pp_opt_verbose=true
58
59pp_main_cleanup () {
60	pp_debug "main_cleanup"
61        pp_remove_later_now
62	if $pp_opt_no_clean || test x"$pp_platform" = x"unknown"; then
63	    : no cleanup
64	else
65	    pp_backend_${pp_platform}_cleanup
66	    $pp_errors && pp_die "Errors during cleanup"
67	    if test -d "$pp_wrkdir"; then
68		if $pp_opt_debug; then
69		    pp_debug "not removing $pp_wrkdir"
70		else
71		    pp_verbose rm -rf "$pp_wrkdir"
72		fi
73	    fi
74	fi
75}
76
77pp_parseopts () {
78        typeset a n _var _val
79	while test $# -gt 0; do
80
81	  # convert -[dilpv] to --long-options
82	  case "$1" in
83	    --?*=?*) n=`echo "$1" | sed -ne 's/^--\([^=]*\)=.*/\1/p'`
84	           a=`echo "$1" | sed -ne 's/^--[^=]*=\(.*\)/\1/p'`
85		   shift
86		   set -- "--$n" "$a" "$@";;
87	    --?*) : ;;
88
89	    -d)  shift; set -- "--debug" "$@";;
90	    -d*) a=`echo "$1" | sed -ne 's/^-.//'`
91		 shift; set -- "--debug" "$@";;
92
93	    -i) shift; set -- "--install-script" "$@";;
94	    -i*) a=`echo "$1" | sed -ne 's/^-.//'`
95		 shift; set -- "--install-script" "$a" "$@";;
96
97	    -l)  shift; set -- "--list" "$@";;
98	    -l*) a=`echo "$1" | sed -ne 's/^-.//'`
99		 shift; set -- "--list" "$@";;
100
101	    -p) shift; set -- "--platform" "$@";;
102	    -p*) a=`echo "$1" | sed -ne 's/^-.//'`
103		 shift; set -- "--platform" "$a" "$@";;
104
105	    -v)  shift; set -- "--verbose" "$@";;
106	    -v*) a=`echo "$1" | sed -ne 's/^-.//'`
107		 shift; set -- "--verbose" "$@";;
108
109	    -\?)  shift; set -- "--help" "$@";;
110	    -\?*) a=`echo "$1" | sed -ne 's/^-.//'`
111		 shift; set -- "--help" "$@";;
112	  esac
113
114	  case "$1" in
115	    --destdir|--eval|--install-script|--platform|--wrkdir)
116		test $# -ge 2 || pp_error "missing argument to $1";;
117	  esac
118
119	  case "$1" in
120	    --) 				       shift;break;;
121	    --debug)           pp_opt_debug=true;      shift;;
122	    --destdir)         pp_opt_destdir="$2";    shift;shift;;
123	    --eval)            pp_opt_eval="$2";       shift;shift;; # undoc
124	    --install-script)  pp_opt_install_script="$2"; shift;shift;;
125	    --list)            pp_opt_list=true;       shift;;
126	    --no-clean)        pp_opt_no_clean=true;   shift;;
127	    --no-package)      pp_opt_no_package=true; shift;;
128	    --only-front)      pp_opt_only_front=true; shift;;
129	    --platform)        pp_opt_platform="$2";   shift;shift;;
130	    --probe)           pp_opt_probe=true;      shift;;
131	    --strip)           pp_opt_strip=true;      shift;;
132	    --save-unstripped) pp_opt_save_unstripped=true; shift;;
133	    --wrkdir)          pp_opt_wrkdir="$2";     shift;shift;;
134	    --vas-platforms)   pp_opt_vas_platforms=true; shift;;
135	    --verbose)         pp_opt_verbose=true;    shift;;
136	    --version)         pp_opt_version=true;    shift;;
137	    --help)            pp_errors=true;         shift;;
138	    -) break;;
139	    -*) pp_error "unknown option $1"; shift;;
140	    *) break;;
141	  esac
142
143	done
144
145	pp_opt_input=-
146	if test $# -gt 0; then
147	    pp_opt_input="$1"
148	    shift
149	fi
150
151        #-- extra arguments of the form Foo=bar alter *global* vars
152        while test $# -gt 0; do
153            case "$1" in
154		-*)	pp_error "unexpected option '$1'"
155			shift;;
156                *=*)    _val="${1#*=}"
157                        _var=${1%="$_val"}
158                        _val=`echo "$_val"|sed -e 's/[$"\\]/\\&/g'`
159                        pp_debug "setting $_var = \"$_val\""
160                        pp_opt_init_vars="$pp_opt_init_vars$_var=\"$_val\";"
161                        shift;;
162                *)      pp_error "unexpected argument $1'"
163			shift;;
164            esac
165        done
166
167	test $# -gt 0 &&
168            pp_error "unknown argument $1"
169
170	if $pp_errors; then
171	    cat <<. >&2
172polypkg $pp_version $pp_copyright
173usage: $0 [options] [input.pp] [var=value ...]
174    -d --debug                  -- write copious info to stderr
175       --destdir=path           -- file root, defaults to \$DESTDIR
176    -? --help                   -- display this information
177    -i --install-script=path    -- create an install helper script
178    -l --list                   -- write package filenames to stdout
179       --no-clean               -- don't remove temporary files
180       --no-package             -- do everything but create packages
181       --only-front             -- only perform front-end actions
182    -p --platform=platform      -- defaults to local platform
183       --probe                  -- print local system identifier, then exit
184       --strip                  -- strip debug symbols from binaries before
185                                   packaging (modifies files in destdir)
186       --save-unstripped        -- save unstripped binaries to
187                                   \$name-\$version-unstripped.tar.gz
188       --wrkdir=path            -- defaults to subdirectory of \$TMPDIR or /tmp
189    -v --verbose                -- write info to stderr
190       --version                -- display version and quit
191.
192	    exit 1
193	fi
194}
195
196pp_drive () {
197	# initialise the front and back ends
198        pp_model_init
199	pp_frontend_init
200	$pp_opt_only_front || pp_backend_init
201
202	# run the front-end to generate the intermediate files
203        # set $pp_input_dir to be the 'include dir' if needed
204	pp_debug "calling frontend on $pp_opt_input"
205	case "$pp_opt_input" in
206	    -)   pp_input_dir=.
207		 test -t 1<&0 &&
208		    pp_warn "reading directives from standard input"
209                 pp_frontend
210                 ;;
211            */*) pp_input_dir=${pp_opt_input%/*}
212	         pp_frontend <"$pp_opt_input"
213                 ;;
214            *)   pp_input_dir=.
215	         pp_frontend <"$pp_opt_input"
216                 ;;
217	esac
218
219        pp_files_ignore_others
220        pp_service_scan_groups
221
222	# some sanity checks after front-end processing
223        if test x"$pp_platform" != x"null"; then
224	    pp_debug "sanity checks"
225	    test -n "$pp_components" || pp_error "No components?"
226	    pp_check_var_is_defined  "name"
227	    pp_check_var_is_defined  "version"
228            pp_files_check_duplicates
229            pp_files_check_coverage
230	    pp_die_if_errors "Errors during sanity checks"
231        fi
232
233	# stop now if we're only running the front
234	$pp_opt_only_front && return
235
236	if test x"$pp_opt_strip" = x"true"; then
237	    pp_strip_binaries
238	fi
239
240	# run the back-end to generate the package
241	pp_debug "calling backend"
242	pp_backend
243	pp_die_if_errors "Errors during backend processing"
244
245	# copy the resulting package files to PP_PKGDESTDIR or .
246	for f in `pp_backend_names` -; do
247           test x"$f" = x"-" && continue
248	   pp_debug "copying: $f to `pwd`"
249	   if pp_verbose cp -r $pp_wrkdir/$f ${PP_PKGDESTDIR:-.}; then
250               echo "${PP_PKGDESTDIR:+$PP_PKGDESTDIR/}$f"
251           else
252               pp_error "$f: missing package"
253           fi
254	done
255	pp_die_if_errors "Errors during package copying"
256}
257
258pp_install_script () {
259        pp_debug "writing install script to $pp_opt_install_script"
260        rm -f $pp_opt_install_script
261        pp_backend_install_script > $pp_opt_install_script
262	pp_die_if_errors "Errors during package install script"
263        chmod +x $pp_opt_install_script
264}
265
266pp_main () {
267	# If PP_DEV_PATH is set, then jump to that script.
268	# (Useful when working on polypkg source that isn't installed)
269	if test -n "$PP_DEV_PATH" -a x"$PP_DEV_PATH" != x"$0"; then
270	    pp_warn "switching from $0 to $PP_DEV_PATH ..."
271	    exec "$PP_DEV_PATH" "$@" || exit 1
272	fi
273
274	pp_set_expand_converter_or_reexec "$@"
275	pp_parseopts "$@"
276
277        if $pp_opt_version; then
278            #-- print version and exit
279            echo "polypkg $pp_version"
280            exit 0
281        fi
282
283	pp_set_platform
284
285	trap 'pp_main_cleanup' 0
286
287	pp_wrkdir="$pp_opt_wrkdir"
288	pp_debug "pp_wrkdir = $pp_wrkdir"
289	rm -rf "$pp_wrkdir"
290	mkdir -p "$pp_wrkdir"
291
292	pp_destdir="$pp_opt_destdir"
293	pp_debug "pp_destdir = $pp_destdir"
294
295        if $pp_opt_probe; then
296	    pp_backend_init
297            pp_backend_probe
298        elif $pp_opt_vas_platforms; then
299	    pp_backend_init
300            pp_backend_vas_platforms
301	elif test -n "$pp_opt_eval"; then
302	    #-- execute a shell command
303	    eval "$pp_opt_eval" || exit
304	else
305	    pp_drive
306	    if test -n "$pp_opt_install_script"; then
307		pp_install_script
308	    fi
309        fi
310
311	exit 0
312}
313
314
315pp_errors=false
316
317if test -n "$TERM" -a -t 1 && (tput op) >/dev/null 2>/dev/null; then
318   pp_col_redfg=`tput setf 4` 2>/dev/null
319   pp_col_bluefg=`tput setf 1` 2>/dev/null
320   pp_col_reset=`tput op` 2>/dev/null
321else
322   pp_col_redfg='['
323   pp_col_bluefg='['
324   pp_col_reset=']'
325fi
326
327pp__warn () {
328	if test x"" = x"$pp_lineno"; then
329	    echo "$1 $2" >&2
330	else
331	    echo "$1 line $pp_lineno: $2" >&2
332	fi
333}
334
335pp_warn () {
336	pp__warn "pp: ${pp_col_redfg}warning${pp_col_reset}" "$*"
337}
338
339pp_error () {
340	pp__warn "pp: ${pp_col_redfg}error${pp_col_reset}" "$*"
341	pp_errors=true
342}
343
344pp_die () {
345	pp_error "$@"
346	exit 1
347}
348
349pp_die_if_errors () {
350	$pp_errors && pp_die "$@"
351}
352
353pp_debug () {
354	$pp_opt_debug && echo "${pp_col_bluefg}debug${pp_col_reset} $*" >&2
355}
356
357pp_verbose () {
358	$pp_opt_verbose && echo "pp: ${pp_col_bluefg}info${pp_col_reset} $*" >&2
359	"$@";
360}
361
362pp_substitute () {
363  sed -e 's,%(\([^)]*\)),`\1`,g' \
364      -e 's,%{\([^}]*\)},${\1},g' \
365      -e 's,$,,' |
366  tr '' '\012' |
367  sed -e '/^[^]/s/["$`\\]/\\&/g' \
368      -e 's/^//' \
369      -e '1s/^/echo "/' \
370      -e '$s,$,",' \
371      -e 's,,"echo ",g' |
372  tr -d '\012' |
373  tr '' '\012'
374  echo
375}
376
377pp_incr () {
378    eval "$1=\`expr \$$1 + 1\`"
379}
380
381pp_decr () {
382    eval "$1=\`expr \$$1 - 1\`"
383}
384
385pp_check_var_is_defined () {
386    if eval test -z "\"\$$1\""; then
387	pp_error "\$$1: not set"
388	eval "$1=undefined"
389    fi
390}
391
392pp_contains () {
393    case " $1 " in
394       *" $2 "*) return 0;;
395       *) return 1;;
396    esac
397}
398
399pp_contains_all () {
400    typeset _s _c
401    _l="$1"; shift
402    for _w
403    do
404	pp_contains "$_l" "$_w" || return 1
405    done
406    return 0
407}
408
409pp_contains_any () {
410    typeset _s _c
411    _l="$1"; shift
412    for _w
413    do
414	pp_contains "$_l" "$_w" && return 0
415    done
416    return 1
417}
418
419pp_add_to_list () {
420    if eval test -z \"\$$1\"; then
421	eval $1='"$2"'
422    elif eval pp_contains '"$'$1'"' '"$2"'; then
423	: already there
424    else
425	eval $1='"$'$1' $2"'
426    fi
427}
428
429pp_unique () {
430    typeset result element
431    result=
432    for element
433    do
434	pp_add_to_list result $element
435    done
436    echo $result
437}
438
439pp_mode_strip_altaccess () {
440    case "$1" in
441	??????????[+.])
442	    echo `echo "$1" | cut -b -10`;;
443	*)
444	    echo "$1";;
445    esac
446}
447
448pp_mode_from_ls () {
449   typeset umode gmode omode smode
450
451   set -- `pp_mode_strip_altaccess "$1"`
452
453   case "$1" in
454	?--[-X]??????) umode=0;;
455	?--[xs]??????) umode=1;;
456	?-w[-X]??????) umode=2;;
457	?-w[xs]??????) umode=3;;
458	?r-[-X]??????) umode=4;;
459	?r-[xs]??????) umode=5;;
460	?rw[-X]??????) umode=6;;
461	?rw[xs]??????) umode=7;;
462	*) pp_error "bad user mode $1";;
463   esac
464
465   case "$1" in
466	????--[-S]???) gmode=0;;
467	????--[xs]???) gmode=1;;
468	????-w[-S]???) gmode=2;;
469	????-w[xs]???) gmode=3;;
470	????r-[-X]???) gmode=4;;
471	????r-[xs]???) gmode=5;;
472	????rw[-X]???) gmode=6;;
473	????rw[xs]???) gmode=7;;
474	*) pp_error "bad group mode $1";;
475   esac
476
477   case "$1" in
478	???????--[-T]) omode=0;;
479	???????--[xt]) omode=1;;
480	???????-w[-T]) omode=2;;
481	???????-w[xt]) omode=3;;
482	???????r-[-T]) omode=4;;
483	???????r-[xt]) omode=5;;
484	???????rw[-T]) omode=6;;
485	???????rw[xt]) omode=7;;
486	*) pp_error "bad other mode $1";;
487   esac
488
489   case "$1" in
490	???[-x]??[-x]??[-x]) smode=;;
491	???[-x]??[-x]??[tT]) smode=1;;
492	???[-x]??[Ss]??[-x]) smode=2;;
493	???[-x]??[Ss]??[tT]) smode=3;;
494	???[Ss]??[-x]??[-x]) smode=4;;
495	???[Ss]??[-x]??[tT]) smode=5;;
496	???[Ss]??[Ss]??[-x]) smode=6;;
497	???[Ss]??[Ss]??[tT]) smode=7;;
498	*) pp_error "bad set-id mode $1";;
499   esac
500
501   echo "$smode$umode$gmode$omode"
502}
503
504pp_find_recurse () {
505  pp_debug "find: ${1#$pp_destdir}/"
506  for f in "$1"/.* "$1"/*; do
507    case "$f" in */.|*/..) continue;; esac  # should never happen!
508    if test -d "$f" -o -f "$f" -o -h "$f"; then
509        if test -d "$f" -a ! -h "$f"; then
510            echo "${f#$pp_destdir}/"
511            pp_find_recurse "$f"
512        else
513            echo "${f#$pp_destdir}"
514        fi
515    fi
516  done
517}
518
519pp_prepend () {
520    #test -t && pp_warn "pp_prepend: stdin is a tty?"
521    if test -f $1; then
522        pp_debug "prepending to $1"
523        mv $1 $1._prepend
524        cat - $1._prepend >$1
525        rm -f $1._prepend
526    else
527        pp_debug "prepend: creating $1"
528        cat >$1
529    fi
530}
531
532pp_note_file_used() {
533    echo "$1" >> $pp_wrkdir/all.files
534}
535
536pp_create_dir_if_missing () {
537    case "$1" in
538        */) pp_error "pp_create_dir_if_missing: trailing / forbidden";;
539	"") return 0;;
540	*)  if test ! -d "$pp_destdir$1"; then
541                pp_debug "fabricating directory $1/"
542		pp_create_dir_if_missing "${1%/*}"
543		mkdir "$pp_destdir$1" &&
544                    pp_note_file_used "$1/"
545		pp_remove_later "$1" &&
546		chmod ${2:-755} "$pp_destdir$1"
547	    fi;;
548    esac
549}
550
551pp_add_file_if_missing () {
552    typeset dir
553    #-- check that the file isn't already declared in the component
554    if test -s $pp_wrkdir/%files.${2:-run}; then
555      awk "\$6 == \"$1\" {exit 1}" < $pp_wrkdir/%files.${2:-run} || return 1
556    fi
557
558    pp_create_dir_if_missing "${1%/*}"
559    pp_debug "fabricating file $1"
560    echo "f ${3:-755} - - ${4:--} $1" >> $pp_wrkdir/%files.${2:-run}
561    pp_note_file_used "$1"
562    pp_remove_later "$1"
563    return 0
564}
565
566pp_add_transient_file () {
567    test -f "$pp_destdir$1" && pp_die "$pp_destdir$1: exists"
568    pp_create_dir_if_missing "${1%/*}"
569    pp_debug "transient file $1"
570    pp_note_file_used "$1"
571    pp_remove_later "$1"
572}
573
574pp_remove_later () {
575   {
576	echo "$1"
577	test -s $pp_wrkdir/pp_cleanup && cat $pp_wrkdir/pp_cleanup
578   } > $pp_wrkdir/pp_cleanup.new
579   mv $pp_wrkdir/pp_cleanup.new $pp_wrkdir/pp_cleanup
580}
581
582pp_ls_readlink () {
583    if test -h "$1"; then
584        ls -1ld "$1" | sed -ne 's,.* -> ,,p'
585    else
586        echo "$1: not a symbolic link" >&2
587        return 1
588    fi
589}
590
591pp_remove_later_now () {
592    typeset f
593    if test -s $pp_wrkdir/pp_cleanup; then
594        pp_debug "pp_remove_later_now"
595        while read f; do
596            pp_debug "removing $pp_destdir$f"
597	    if test -d $pp_destdir$f; then
598		rmdir $pp_destdir$f
599	    else
600		rm $pp_destdir$f
601	    fi
602        done < $pp_wrkdir/pp_cleanup
603        rm $pp_wrkdir/pp_cleanup
604    fi
605}
606
607pp_readlink() {
608
609pp_debug "&& pp_readlink_fn=$pp_readlink_fn"
610
611    if test -n "$pp_readlink_fn"; then
612pp_debug "&& calling $pp_readlink_fn $*"
613        "$pp_readlink_fn" "$@"
614    else
615        readlink "$@"
616    fi
617}
618
619
620pp_install_script_common () {
621        cat <<-.
622
623            # Automatically generated for
624            #    $name $version ($pp_platform)
625            # by PolyPackage $pp_version
626
627            usage () {
628              case "$1" in
629              "list-services")
630                echo "usage: \$0 list-services" ;;
631              "list-components")
632                echo "usage: \$0 list-components" ;;
633              "list-files")
634                echo "usage: \$0 list-files {cpt...|all}" ;;
635              "install")
636                echo "usage: \$0 install {cpt...|all}" ;;
637              "uninstall")
638                echo "usage: \$0 uninstall {cpt...|all}" ;;
639              "start")
640                echo "usage: \$0 start {svc...}" ;;
641              "stop")
642                echo "usage: \$0 stop {svc...}" ;;
643              "print-platform")
644                echo "usage: \$0 print-platform" ;;
645              *)
646                echo "usage: \$0 [-q] command [args]"
647                echo "   list-services"
648                echo "   list-components"
649                echo "   list-files {cpt...|all}"
650                echo "   install {cpt...|all}"
651                echo "   uninstall {cpt...|all}"
652                echo "   start {svc...}"
653                echo "   stop {svc...}"
654                echo "   print-platform"
655                ;;
656              esac >&2
657              exit 1
658            }
659
660            if test x"\$1" = x"-q"; then
661                shift
662                verbose () { "\$@"; }
663                verbosemsg () { : ; }
664            else
665                verbose () { echo "+ \$*"; "\$@"; }
666                verbosemsg () { echo "\$*"; }
667            fi
668.
669}
670
671
672pp_functions () {
673    typeset func deps allfuncs
674    allfuncs=
675    while test $# -gt 0; do
676	pp_add_to_list allfuncs "$1"
677	deps=`pp_backend_function "$1:depends"`
678	shift
679	set -- `pp_unique "$@" $deps`
680    done
681
682    for func in $allfuncs
683    do
684        pp_debug "generating function code for '$1'"
685        echo ""
686        echo "$func () {"
687	case "$func" in
688	    pp_mkgroup|pp_mkuser|pp_havelib) echo <<.;;
689		if test \$# -lt 1; then
690		    echo "$func: not enough arguments" >&2
691		    return 1
692		fi
693.
694	esac
695        pp_backend_function "$func" || cat <<.
696		echo "$func: not implemented" >&2
697		return 1
698.
699        echo "}"
700    done
701}
702
703pp_function () {
704    pp_functions "$1"
705}
706
707pp_makevar () {
708    #-- convert all non alpha/digits to underscores
709    echo "$*" | tr -c '[a-z][A-Z][0-9]\012' '[_*]'
710}
711
712pp_getpwuid () {
713    awk -F: '$3 == uid { if (!found) print $1; found=1; } END { if (!found) exit 1; }' uid="$1" \
714	< /etc/passwd || pp_error "no local username for uid $1"
715}
716
717pp_getgrgid () {
718    awk -F: '$3 == gid { if (!found) print $1; found=1; } END { if (!found) exit 1; }' gid="$1" \
719	< /etc/group || pp_error "no local group for gid $1"
720}
721
722pp_backend_function_getopt () {
723    cat <<'..'
724pp_getopt () {
725     _pp_optstring="$1"; shift; eval `_pp_getopt "$_pp_optstring"`
726}
727_pp_getopt_meta=s,[\\\\\"\'\`\$\&\;\(\)\{\}\#\%\ \	],\\\\\&,g
728_pp_protect () {
729    sed "$_pp_getopt_meta" <<. | tr '\012' ' '
730$*
731.
732}
733_pp_protect2 () {
734    sed "s,^..,,$pp_getopt_meta" <<. | tr '\012' ' '
735$*
736.
737}
738_pp_nonl () {
739    tr '\012' ' ' <<.
740$*
741.
742}
743_pp_getopt () {
744    _pp_nonl '_pp_nonl set --; while test $# -gt 0; do case "$1" in "--") shift; break;;'
745    sed 's/\([^: 	]:*\)/<@<\1>@>/g;
746	 s/<@<\(.\):>@>/"-\1")  _pp_nonl -"\1"; _pp_protect "$2"; shift; shift;; "-\1"*) _pp_nonl -"\1"; _pp_protect2 "$1"; shift;;/g;s/<@<\(.\)>@>/ "-\1")  _pp_nonl -"\1"; shift;; "-\1"*) _pp_nonl -"\1"; _pp_tmp="$1"; shift; set -- -`_pp_protect2 "$_pp_tmp"` "$@";;/g' <<.
747$1
748.
749    _pp_nonl '-*) echo "$1: unknown option">&2; return 1;; *) break;; esac; done; _pp_nonl --; while test $# -gt 0; do _pp_nonl "$1"; shift; done; echo'
750    echo
751}
752..
753}
754
755pp_copy_unstripped () {
756    typeset filedir realdir
757    filedir="`dirname ${1#$pp_destdir}`"
758    realdir="$pp_wrkdir/unstripped/$filedir"
759
760    mkdir -p "$realdir"
761    # Can't use hardlinks because `strip` modifies the original file in-place
762    cp "$1" "$realdir"
763}
764
765pp_package_stripped_binaries () {
766    (cd "$pp_wrkdir/unstripped" && tar -c .) \
767     | gzip > "$name-dbg-$version.tar.gz"
768    rm -rf "$pp_wrkdir/unstripped"
769}
770
771pp_strip_binaries () {
772    if test x"$pp_opt_save_unstripped" = x"true"; then
773	rm  -rf "$pp_wrkdir/unstripped"
774	mkdir "$pp_wrkdir/unstripped"
775    fi
776
777    for f in `find "$pp_destdir" -type f`; do
778	if file "$f" | awk '{print $2}' | grep ^ELF >/dev/null 2>&1; then
779	    if test x"$pp_opt_save_unstripped" = x"true"; then
780		if file "$f" | LC_MESSAGES=C grep 'not stripped' >/dev/null 2>&1; then
781		    pp_debug "Saving unstripped binary $f"
782		    pp_copy_unstripped "$f"
783		else
784		    pp_debug "$f is already stripped; not saving a copy"
785		fi
786	    fi
787	    pp_debug "Stripping unnecessary symbols from $f"
788	    strip "$f"
789	fi
790    done
791
792    if test x"$pp_opt_save_unstripped" = x"true"; then
793	pp_package_stripped_binaries
794    fi
795}
796
797pp_if_true=0
798pp_if_false=0
799
800pp_frontend_init () {
801    name=
802    version=
803    summary="no summary"
804    description="No description"
805    copyright="Copyright 2012 Quest Software, Inc. ALL RIGHTS RESERVED."
806
807    #-- if the user supplied extra arguments on the command line
808    #   then load them now.
809    pp_debug "pp_opt_init_vars=$pp_opt_init_vars"
810    test -n "$pp_opt_init_vars" && eval "$pp_opt_init_vars"
811}
812
813pp_is_qualifier () {
814    typeset ret
815
816    case "$1" in
817        "["*"]") ret=true;;
818        *)       ret=false;;
819    esac
820    pp_debug "is_qualifier: $* -> $ret"
821    test $ret = true
822}
823
824pp_eval_qualifier () {
825    typeset ret
826
827    case "$1" in
828        "[!$pp_platform]"| \
829         "[!"*",$pp_platform]"| \
830         "[!$pp_platform,"*"]"| \
831         "[!"*",$pp_platform,"*"]") ret=false;;
832        "[!"*"]") ret=true;;
833        "[$pp_platform]"| \
834         "["*",$pp_platform]"| \
835         "[$pp_platform,"*"]"| \
836         "["*",$pp_platform,"*"]") ret=true;;
837        "["*"]") ret=false;;
838        *) pp_die "pp_eval_qualifier: bad qualifier '$1'"
839    esac
840    pp_debug "eval: $* -> $ret"
841    test true = $ret
842}
843
844pp_frontend_if () {
845    typeset ifcmd ifret
846    ifcmd="$1";
847    shift
848    case "$ifcmd" in
849	%if) if test 0 = $pp_if_false; then
850		case "$*" in
851		    true |1) pp_incr pp_if_true;;
852		    false|0) pp_incr pp_if_false;;
853                    *)
854			ifret=true
855                        if pp_is_qualifier "$*"; then
856                            pp_eval_qualifier "$*" || ifret=false
857                        else
858			    eval test "$@" || ifret=false
859			    pp_debug "evaluating test $* -> $ifret"
860			fi
861			pp_incr pp_if_$ifret
862                        ;;
863		esac
864	     else
865		pp_incr pp_if_false
866	     fi;;
867	%else)  test $# = 0 || pp_warn "ignoring argument to %else"
868		if test $pp_if_false -gt 1; then
869		  : no change
870		elif test $pp_if_false = 1; then
871		  pp_incr pp_if_true
872		  pp_decr pp_if_false
873		elif test $pp_if_true = 0; then
874		  pp_die "unmatched %else"
875		else
876		  pp_incr pp_if_false
877		  pp_decr pp_if_true
878		fi;;
879	%endif) test $# = 0 || pp_warn "ignoring argument to %endif"
880		if test $pp_if_false -gt 0; then
881		  pp_decr pp_if_false
882		elif test $pp_if_true -gt 0; then
883		  pp_decr pp_if_true
884		else
885		  pp_die "unmatched %endif"
886		fi;;
887	*) pp_die "frontend_if: unknown cmd $ifcmd";;
888    esac
889}
890
891
892pp_frontend () {
893  typeset section newsection sed_word sed_ws line cpt svc
894  typeset section_enabled newsection_enabled s sed sed_candidate
895
896  section='%_initial'
897  newsection='%_initial'
898  section_enabled=:
899  newsection_enabled=:
900  sed_word="[a-zA-Z_][a-zA-Z_0-9]*"
901  sed_ws="[ 	]"
902
903  #-- not all seds are created equal
904  sed=
905  for sed_candidate in ${PP_SED:-sed} /usr/xpg4/bin/sed; do
906      if echo 'foo' | $sed_candidate -ne '/^\(x\)*foo/p' | grep foo > /dev/null
907      then
908        sed="$sed_candidate"
909        break
910      fi
911  done
912  test -z "$sed" &&
913        pp_die "sed is broken on this system"
914
915  pp_lineno=0
916
917  #-- Note: this sed script should perform similar to pp_eval_qualifier()
918  $sed -e "/^#/s/.*//" \
919       -e "/^\\[!\\($sed_word,\\)*$pp_platform\\(,$sed_word\\)*\\]/s/.*//" \
920       -e "s/^\\[\\($sed_word,\\)*$pp_platform\\(,$sed_word\\)*\\]$sed_ws*//" \
921       -e "s/^\\[!\\($sed_word,\\)*$sed_word\\]$sed_ws*//" \
922       -e "/^\\[\\($sed_word,\\)*$sed_word\\]/s/.*//" \
923       -e "s/^%$sed_ws*/%/" \
924       -e "s/^$sed_ws/%\\\\&/" \
925     > $pp_wrkdir/frontend.tmp
926
927  #-- add an ignore section at the end to force section completion
928  echo '%ignore' >> $pp_wrkdir/frontend.tmp
929  echo  >> $pp_wrkdir/frontend.tmp
930
931  exec 0<$pp_wrkdir/frontend.tmp
932  : > $pp_wrkdir/tmp
933  : > $pp_wrkdir/%fixup
934  while read -r line; do
935     #-- Convert leading double-% to single-%, or switch sections
936     pp_incr pp_lineno
937
938     pp_debug "line $pp_lineno: $line"
939     set -f
940     set -- $line
941     set +f
942     #pp_debug "line $pp_lineno: $*"
943
944     case "$line" in %*)
945        case "$1" in
946	   %if|%else|%endif)
947                pp_debug "processing if directive $1"
948	   	pp_frontend_if "$@"
949		continue;;
950	esac
951	test 0 -ne $pp_if_false && continue	# ignore lines %if'd out
952
953        case "$1" in
954	  %set|%fixup|%ignore)
955             pp_debug "processing new section $1"
956	     newsection="$1"; shift
957             newsection_enabled=:
958             if pp_is_qualifier "$1"; then
959                pp_eval_qualifier "$1" || newsection_enabled=false
960                shift
961             fi
962	     test $# -eq 0 || pp_warn "ignoring extra arguments: $line"
963	     continue;;
964	  %pre|%post|%preun|%postup|%postun|%files|%depend|%check|%conflict)
965             pp_debug "processing new component section $*"
966             s="$1"; shift
967             if test $# -eq 0 || pp_is_qualifier "$1"; then
968                cpt=run
969             else
970                cpt="$1"
971                shift
972             fi
973             newsection="$s.$cpt"
974             newsection_enabled=:
975             if test $# -gt 0 && pp_is_qualifier "$1"; then
976                pp_eval_qualifier "$1" || newsection_enabled=false
977                shift
978             fi
979             test $# -eq 0 ||
980                pp_warn "ignoring extra arguments: $line"
981             case "$cpt" in
982                run|dbg|doc|dev)
983                    $newsection_enabled && pp_add_component "$cpt";;
984                x-*) :;;    # useful for discarding stuff
985                *) pp_error "unknown component: $1 $cpt";;
986             esac
987	     continue;;
988          %pp)
989            newsection="%ignore"; shift
990            if test $# -gt 0; then
991                pp_set_api_version "$1"
992                shift
993            else
994                pp_error "%pp: missing version"
995            fi
996            test $# -gt 0 &&
997                pp_error "%pp: too many arguments"
998            continue;;
999	  %service)
1000             pp_debug "processing new service section $1 $2"
1001             s="$1"; shift
1002             if test $# -eq 0 || pp_is_qualifier "$1"; then
1003                pp_error "$s: service name required"
1004                svc=unknown
1005             else
1006                svc="$1"; shift
1007             fi
1008
1009	     newsection="$s.$svc"
1010             newsection_enabled=:
1011	     if test $# -gt 0 && pp_is_qualifier "$1"; then
1012                pp_eval_qualifier "$1" || newsection_enabled=false
1013                shift
1014             fi
1015             test $# -eq 0 ||
1016                pp_warn "ignoring extra arguments: $line"
1017	     $newsection_enabled && pp_add_service "$svc"
1018	     continue;;
1019	  %\\*)
1020             pp_debug "removing leading %\\"
1021	     line="${line#??}"
1022             pp_debug "  result is <$line>"
1023             set -f
1024             set -- $line
1025             set +f
1026             ;;
1027	  %%*)
1028             pp_debug "removing leading %"
1029	     line="${line#%}"
1030             set -f
1031             set -- $line
1032             set +f
1033	     ;;
1034	  %*)
1035	     pp_error "unknown section $1"
1036	     newsection='%ignore'
1037             newsection_enabled=:
1038	     continue;;
1039	esac;;
1040     esac
1041
1042     test 0 != $pp_if_false && continue	# ignore lines %if'd out
1043
1044     pp_debug "section=$section (enabled=$section_enabled) newsection=$newsection (enabled=$newsection_enabled)"
1045
1046     #-- finish processing a previous section
1047     if test x"$newsection" != x""; then
1048      $section_enabled && case "$section" in
1049     	%ignore|%_initial)
1050                pp_debug "leaving ignored section $section"
1051		: ignore  # guaranteed to be the last section
1052		;;
1053	%set)
1054                pp_debug "leaving $section: sourcing $pp_wrkdir/tmp"
1055                $pp_opt_debug && cat $pp_wrkdir/tmp >&2
1056		. $pp_wrkdir/tmp
1057		: > $pp_wrkdir/tmp
1058		;;
1059	%pre.*|%preun.*|%post.*|%postup.*|%postun.*|%depend.*|%check.*|%conflict.*|%service.*|%fixup)
1060                pp_debug "leaving $section: substituting $pp_wrkdir/tmp"
1061                # cat $pp_wrkdir/tmp >&2    # debugging
1062                $pp_opt_debug && pp_substitute < $pp_wrkdir/tmp >&2
1063		pp_substitute < $pp_wrkdir/tmp > $pp_wrkdir/tmp.sh
1064                . $pp_wrkdir/tmp.sh >> $pp_wrkdir/$section ||
1065                    pp_error "shell error in $section"
1066		rm -f $pp_wrkdir/tmp.sh
1067		: > $pp_wrkdir/tmp
1068		;;
1069      esac
1070      section="$newsection"
1071      section_enabled="$newsection_enabled"
1072      newsection=
1073     fi
1074
1075     #-- ignore section content that is disabled
1076     $section_enabled || continue
1077
1078     #-- process some lines in-place
1079     case "$section" in
1080	%_initial)
1081		case "$line" in "") continue;; esac # ignore non-section blanks
1082		pp_die "Ignoring text before % section introducer";;
1083	%set|%pre.*|%preun.*|%post.*|%postup.*|%postun.*|%check.*|%service.*|%fixup)
1084                pp_debug "appending line to \$pp_wrkdir/tmp"
1085		echo "$line" >> $pp_wrkdir/tmp
1086		;;
1087	%files.*)
1088		test $# -eq 0 && continue;
1089		pp_files_expand "$@" >> $pp_wrkdir/$section
1090		;;
1091	%depend.*)
1092		pp_debug "Adding explicit dependency $@ to $cpt"
1093		echo "$@" >> $pp_wrkdir/%depend.$cpt
1094		;;
1095	%conflict.*)
1096		pp_debug "Adding explicit conflict $@ to $cpt"
1097		echo "$@" >> $pp_wrkdir/%conflict.$cpt
1098		;;
1099     esac
1100  done
1101  exec <&-
1102
1103  if test $pp_if_true != 0 -o $pp_if_false != 0; then
1104	pp_die "missing %endif at end of file"
1105  fi
1106
1107  pp_lineno=
1108
1109  pp_debug " name        = $name"
1110  pp_debug " version     = $version"
1111  pp_debug " summary     = $summary"
1112  pp_debug " description = $description"
1113  pp_debug " copyright   = $copyright"
1114  pp_debug ""
1115  pp_debug "\$pp_components: $pp_components"
1116  pp_debug "\$pp_services:   $pp_services"
1117}
1118
1119pp_set_api_version() {
1120    case "$1" in
1121        1.0)    : ;;
1122        *)      pp_error "This version of polypackage is too old";;
1123    esac
1124}
1125
1126pp_platform=
1127
1128pp_set_platform () {
1129    if test -n "$pp_opt_platform"; then
1130	pp_contains "$pp_platforms" "$pp_opt_platform" ||
1131		pp_die "$pp_opt_platform: unknown platform"
1132	pp_platform="$pp_opt_platform"
1133    else
1134	uname_s=`uname -s 2>/dev/null`
1135	pp_platform=
1136	for p in $pp_platforms; do
1137	    pp_debug "probing for platform $p"
1138	    if eval pp_backend_${p}_detect "$uname_s"; then
1139		pp_platform="$p"
1140		break;
1141	    fi
1142	done
1143	test -z "$pp_platform" &&
1144		pp_die "cannot detect platform (supported: $pp_platforms)"
1145    fi
1146    pp_debug "pp_platform = $pp_platform"
1147}
1148
1149pp_expand_path=
1150
1151pp_expand_test_usr_bin () {
1152	awk '$1 == "/usr" || $2 == "/usr" {usr++}
1153	     $1 == "/bin" || $2 == "/bin" {bin++}
1154	     END { if (usr == 1 && bin == 1) exit(0); else exit(1); }'
1155}
1156
1157pp_set_expand_converter_or_reexec () {
1158    test -d /usr -a -d /bin ||
1159	pp_die "missing /usr or /bin"
1160    echo /usr /bin | pp_expand_test_usr_bin || pp_die "pp_expand_test_usr_bin?"
1161    if (eval "echo /{usr,bin}" | pp_expand_test_usr_bin) 2>/dev/null; then
1162	pp_expand_path=pp_expand_path_brace
1163    elif (eval "echo /@(usr|bin)" | pp_expand_test_usr_bin) 2>/dev/null; then
1164	pp_expand_path=pp_expand_path_at
1165    else
1166	test x"$pp_expand_rexec" != x"true" ||
1167	    pp_die "problem finding shell that can do brace expansion"
1168	for shell in ksh ksh93 bash; do
1169	    if ($shell -c 'echo /{usr,bin}' |
1170			pp_expand_test_usr_bin) 2>/dev/null ||
1171	       ($shell -c 'echo /@(usr|bin)' |
1172			pp_expand_test_usr_bin) 2>/dev/null
1173	    then
1174                pp_debug "switching to shell $shell"
1175		pp_expand_rexec=true exec $shell "$0" "$@"
1176	    fi
1177	done
1178	pp_die "cannot find a shell that does brace expansion"
1179    fi
1180}
1181
1182pp_expand_path_brace () {
1183	typeset f
1184	eval "for f in $1; do echo \"\$f\"; done|sort -u"
1185}
1186
1187pp_expand_path_at () {
1188	typeset f
1189	eval "for f in `
1190	    echo "$1" | sed -e 's/{/@(/g' -e 's/}/)/g' -e 's/,/|/g'
1191		`; do echo \"\$f\"; done|sort -u"
1192}
1193
1194pp_shlib_suffix='.so*'
1195
1196pp_model_init () {
1197    #@ $pp_components: whitespace-delimited list of components seen in %files
1198    pp_components=
1199    #@ $pp_services: whitespace-delimited list of %service seen
1200    pp_services=
1201
1202    rm -f $pp_wrkdir/%files.* \
1203          $pp_wrkdir/%post.* \
1204          $pp_wrkdir/%pre.* \
1205          $pp_wrkdir/%preun.* \
1206          $pp_wrkdir/%postup.* \
1207          $pp_wrkdir/%postun.* \
1208          $pp_wrkdir/%service.* \
1209          $pp_wrkdir/%set \
1210          $pp_wrkdir/%fixup
1211}
1212
1213
1214pp_have_component () {
1215	pp_contains "$pp_components" "$1"
1216}
1217
1218pp_have_all_components () {
1219	pp_contains_all "$pp_components" "$@"
1220}
1221
1222pp_add_component () {
1223	pp_add_to_list 'pp_components' "$1"
1224}
1225
1226pp_add_service () {
1227	pp_add_to_list 'pp_services' "$1"
1228}
1229
1230pp_service_init_vars () {
1231	cmd=
1232	pidfile=
1233	stop_signal=15		# SIGTERM
1234	user=root
1235	group=
1236	enable=yes		# make it so the service starts on boot
1237	optional=no		# Whether installing this service is optional
1238	pp_backend_init_svc_vars
1239}
1240
1241pp_service_check_vars () {
1242	test -n "$cmd" ||
1243		pp_error "%service $1: cmd not defined"
1244	case "$enable" in
1245	    yes|no) : ;;
1246	    *) pp_error "%service $1: \$enable must be set to yes or no";;
1247	esac
1248}
1249
1250pp_load_service_vars () {
1251	pp_service_init_vars
1252	. "$pp_wrkdir/%service.$1"
1253	pp_service_check_vars "$1"
1254}
1255
1256pp_files_expand () {
1257    typeset _p _mode _group _owner _flags _path _optional _has_target _tree
1258    typeset _path _file _tgt _m _o _g _f _type _lm _ll _lo _lg _ls _lx
1259    typeset _ignore _a
1260
1261    test $# -eq 0 && return
1262
1263    pp_debug "pp_files_expand: path is: $1"
1264
1265    case "$1" in "#"*) return;; esac
1266    _p="$1"; shift
1267
1268    pp_debug "pp_files_expand: other arguments: $*"
1269
1270    #-- the mode must be an octal number of at least three digits
1271    _mode="="
1272    _a=`eval echo \"$1\"`
1273    case "$_a" in
1274	*:*) :;;
1275	-|=|[01234567][01234567][01234567]*) _mode="$_a"; shift;;
1276    esac
1277
1278    #-- the owner:group field may have optional parts
1279    _a=`eval echo \"$1\"`
1280    case "$_a" in
1281	*:*) _group=${_a#*:}; _owner=${_a%:*}; shift;;
1282	=|-) _group=$_a;      _owner=$_a; shift;;
1283	*)   _group=;         _owner=;;
1284    esac
1285
1286    #-- process the flags argument
1287    _flags=
1288    _optional=false
1289    _has_target=false
1290    _ignore=false
1291    if test $# -gt 0; then
1292        _a=`eval echo \"$1\"`
1293	case ",$_a," in *,volatile,*) _flags="${_flags}v";; esac
1294	case ",$_a," in *,optional,*) _optional=true;; esac
1295	case ",$_a," in *,symlink,*) _has_target=true;; esac
1296	case ",$_a," in *,ignore-others,*) _flags="${_flags}i";; esac
1297	case ",$_a," in *,ignore,*) _ignore=true;; esac
1298	shift
1299    fi
1300
1301    #-- process the target argument
1302    if $_has_target; then
1303	test $# -ne 0 || pp_error "$_p: missing target"
1304	_a=`eval echo \"$1\"`
1305	_target="$_a"
1306	shift
1307    fi
1308
1309    pp_debug "pp_files_expand: $_mode|$_owner:$_group|$_flags|$_target|$*"
1310
1311    test $# -eq 0 || pp_error "$_p: too many arguments"
1312
1313    #-- process speciall suffixes
1314    tree=
1315    case "$_p" in
1316        *"/**")  _p="${_p%"/**"}"; tree="**";;
1317        *".%so") _p="${_p%".%so"}$pp_shlib_suffix";;
1318    esac
1319
1320    #-- expand the path using the shell glob
1321    pp_debug "expanding .$_p ... with $pp_expand_path"
1322    (cd ${pp_destdir} && $pp_expand_path ".$_p") > $pp_wrkdir/tmp.files.exp
1323
1324    #-- expand path/** by rewriting the glob output file
1325    case "$tree" in
1326        "") : ;;
1327        "**")
1328            pp_debug "expanding /** tree ..."
1329            while read _path; do
1330                _path="${_path#.}"
1331                pp_find_recurse "$pp_destdir${_path%/}"
1332            done < $pp_wrkdir/tmp.files.exp |
1333                 sort -u > $pp_wrkdir/tmp.files.exp2
1334            mv $pp_wrkdir/tmp.files.exp2 $pp_wrkdir/tmp.files.exp
1335            ;;
1336    esac
1337
1338    while read _path; do
1339	_path="${_path#.}"
1340	_file="${pp_destdir}${_path}"
1341	_tgt=
1342	_m="$_mode"
1343	_o="${_owner:--}"
1344	_g="${_group:--}"
1345	_f="$_flags"
1346
1347        case "$_path" in
1348            /*) :;;
1349            *)  pp_warn "$_path: inserting leading /"
1350                _path="/$_path";;  # ensure leading /
1351        esac
1352
1353        #-- sanity checks
1354        case "$_path" in
1355            */../*|*/..) pp_error "$_path: invalid .. in path";;
1356            */./*|*/.)   pp_warn  "$_path: invalid component . in path";;
1357            *//*)        pp_warn  "$_path: redundant / in path";;
1358        esac
1359
1360	#-- set the type based on the real file's type
1361        if $_ignore; then
1362           _type=f _m=_ _o=_ _g=_
1363	elif test -h "$_file"; then
1364	   case "$_path" in
1365		*/) pp_warn "$_path (symlink $_file): removing trailing /"
1366		    _path="${_path%/}"
1367		    ;;
1368	   esac
1369	   _type=s
1370	   if test x"$_target" != x"=" -a -n "$_target"; then
1371	       _tgt="$_target"
1372pp_debug "symlink target is $_tgt"
1373	   else
1374	       _tgt=`pp_readlink "$_file"`;
1375               test -z "$_tgt" && pp_error "can't readlink $_file"
1376               case "$_tgt" in
1377                    ${pp_destdir}/*)
1378                       pp_warn "stripped \$destdir from symlink ($_path)"
1379                       _tgt="${_tgt#$pp_destdir}";;
1380               esac
1381	   fi
1382	   _m=777
1383	elif test -d "$_file"; then
1384	   #-- display a warning if the user forgot the trailing /
1385	   case "$_path" in
1386		*/) :;;
1387		*) pp_warn "$_path (matching $_file): adding trailing /"
1388		   _path="$_path/";;
1389	   esac
1390	   _type=d
1391	   $_has_target && pp_error "$_file: not a symlink"
1392	elif test -f "$_file"; then
1393	   case "$_path" in
1394		*/) pp_warn "$_path (matching $_file): removing trailing /"
1395		    _path="${_path%/}"
1396		    ;;
1397	   esac
1398	   _type=f
1399	   $_has_target && pp_error "$_file: not a symlink"
1400	else
1401	   $_optional && continue
1402	   pp_error "$_file: missing"
1403	   _type=f
1404	fi
1405
1406	#-- convert '=' shortcuts into mode/owner/group from ls
1407	case ":$_m:$_o:$_g:" in *:=:*)
1408	    if LS_OPTIONS=--color=never /bin/ls -ld "$_file" \
1409		    > $pp_wrkdir/ls.tmp
1410	    then
1411                read _lm _ll _lo _lg _ls _lx < $pp_wrkdir/ls.tmp
1412                test x"$_m" = x"=" && _m=`pp_mode_from_ls "$_lm"`
1413                test x"$_o" = x"=" && _o="$_lo"
1414                test x"$_g" = x"=" && _g="$_lg"
1415            else
1416                pp_error "cannot read $_file"
1417                test x"$_m" = x"=" && _m=-
1418                test x"$_o" = x"=" && _o=-
1419                test x"$_g" = x"=" && _g=-
1420            fi
1421	    ;;
1422	esac
1423
1424	test -n "$_f" || _f=-
1425
1426	#-- sanity checks
1427	test -n "$_type" || pp_die "_type empty"
1428	test -n "$_path" || pp_die "_path empty"
1429	test -n "$_m" || pp_die "_m empty"
1430	test -n "$_o" || pp_die "_o empty"
1431	test -n "$_g" || pp_die "_g empty"
1432
1433	#-- setuid/gid files must be given an explicit owner/group (or =)
1434	case "$_o:$_g:$_m" in
1435	    -:*:[4657][1357]??|-:*:[4657]?[1357]?|-:*:[4657]??[1357])
1436		pp_error "$_path: setuid file ($_m) missing explicit owner";;
1437	    *:-:[2367][1357]??|*:-:[2367]?[1357]?|*:-:[2367]??[1357])
1438		pp_error "$_path: setgid file ($_m) missing explicit group";;
1439	esac
1440
1441	# convert numeric uids into usernames; only works for /etc/passwd
1442	case "$_o" in [0-9]*) _o=`pp_getpwuid $_o`;; esac
1443	case "$_g" in [0-9]*) _g=`pp_getgrgid $_g`;; esac
1444
1445	pp_debug "$_type $_m $_o $_g $_f $_path" $_tgt
1446	$_ignore || echo "$_type $_m $_o $_g $_f $_path" $_tgt
1447        pp_note_file_used "$_path"
1448        case "$_f" in *i*) echo "$_path" >> $pp_wrkdir/ign.files;; esac
1449    done < $pp_wrkdir/tmp.files.exp
1450}
1451
1452pp_files_check_duplicates () {
1453    typeset _path
1454    if test -s $pp_wrkdir/all.files; then
1455        sort < $pp_wrkdir/all.files | uniq -d > $pp_wrkdir/duplicate.files
1456	if test -f $pp_wrkdir/ign.awk; then
1457	    # Remove ignored files
1458	    mv $pp_wrkdir/duplicate.files $pp_wrkdir/duplicate.files.ign
1459	    sed -e 's/^/_ _ _ _ _ /' < $pp_wrkdir/duplicate.files.ign |
1460		awk -f $pp_wrkdir/ign.awk |
1461		sed -e 's/^_ _ _ _ _ //' > $pp_wrkdir/duplicate.files
1462	fi
1463        while read _path; do
1464            pp_warn "$_path: file declared more than once"
1465        done <$pp_wrkdir/duplicate.files
1466    fi
1467}
1468
1469pp_files_check_coverage () {
1470    pp_find_recurse "$pp_destdir" | sort > $pp_wrkdir/coverage.avail
1471    if test -s $pp_wrkdir/all.files; then
1472        sort -u < $pp_wrkdir/all.files
1473    else
1474        :
1475    fi > $pp_wrkdir/coverage.used
1476    join -v1 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
1477        > $pp_wrkdir/coverage.not-packaged
1478    if test -s $pp_wrkdir/coverage.not-packaged; then
1479        pp_warn "The following files/directories were found but not packaged:"
1480        sed -e 's,^,    ,' <  $pp_wrkdir/coverage.not-packaged >&2
1481    fi
1482    join -v2 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
1483        > $pp_wrkdir/coverage.not-avail
1484    if test -s $pp_wrkdir/coverage.not-avail; then
1485        pp_warn "The following files/directories were named but not found:"
1486        sed -e 's,^,    ,' <  $pp_wrkdir/coverage.not-avail >&2
1487    fi
1488}
1489
1490pp_files_ignore_others () {
1491    typeset p f
1492
1493    test -s $pp_wrkdir/ign.files || return
1494
1495    #-- for each file in ign.files, we remove it from all the
1496    #   other %files.* lists, except where it has an i flag.
1497    #   rather than scan each list multiple times, we build
1498    #   an awk script
1499
1500    pp_debug "stripping ignore files"
1501
1502    while read p; do
1503        echo '$6 == "'"$p"'" && $5 !~ /i/ { next }'
1504    done < $pp_wrkdir/ign.files > $pp_wrkdir/ign.awk
1505    echo '{ print }' >> $pp_wrkdir/ign.awk
1506
1507    $pp_opt_debug && cat $pp_wrkdir/ign.awk
1508
1509    for f in $pp_wrkdir/%files.*; do
1510	mv $f $f.ign
1511        awk -f $pp_wrkdir/ign.awk < $f.ign > $f || pp_error "awk"
1512    done
1513}
1514
1515pp_service_scan_groups () {
1516    typeset svc
1517
1518    #-- scan for "group" commands, and build a list of groups
1519    pp_service_groups=
1520    if test -n "$pp_services"; then
1521        for svc in $pp_services; do
1522	    group=
1523	    . $pp_wrkdir/%service.$svc
1524	    if test -n "$group"; then
1525		pp_contains "$pp_services" "$group" && pp_error \
1526		    "%service $svc: group name $group in use by a service"
1527		pp_add_to_list 'pp_service_groups' "$group"
1528		echo "$svc" >> $pp_wrkdir/%svcgrp.$group
1529	    fi
1530        done
1531    fi
1532}
1533
1534pp_service_get_svc_group () {
1535    (tr '\012' ' ' < $pp_wrkdir/%svcgrp.$1 ; echo) | sed -e 's/ $//'
1536}
1537
1538for _sufx in _init '' _names _cleanup _install_script \
1539    _init_svc_vars _function _probe _vas_platforms
1540do
1541 eval "pp_backend$_sufx () { pp_debug pp_backend$_sufx; pp_backend_\${pp_platform}$_sufx \"\$@\"; }"
1542done
1543
1544
1545pp_platforms="$pp_platforms aix"
1546
1547pp_backend_aix_detect () {
1548	test x"$1" = x"AIX"
1549}
1550
1551pp_backend_aix_init () {
1552        pp_aix_detect_arch
1553        pp_aix_detect_os
1554
1555	pp_aix_bosboot=		# components that need bosboot
1556	pp_aix_lang=en_US
1557	pp_aix_copyright=
1558        pp_aix_start_services_after_install=false
1559        pp_aix_init_services_after_install=true
1560
1561        pp_aix_sudo=sudo	# AIX package tools must run as root
1562
1563        case "$pp_aix_os" in
1564            *) pp_readlink_fn=pp_ls_readlink;;  # XXX
1565        esac
1566
1567	pp_aix_abis_seen=
1568}
1569
1570pp_aix_detect_arch () {
1571	pp_aix_arch_p=`uname -p 2>/dev/null`
1572	case "$pp_aix_arch_p"  in
1573	   "")      pp_debug "can't get processor type from uname -p"
1574                    pp_aix_arch_p=powerpc
1575                    pp_aix_arch=R;;  # guess (lsattr -l proc0 ??)
1576	   powerpc) pp_aix_arch=R;;
1577	   *)       pp_aix_arch_p=intel
1578                    pp_aix_arch=I;;  # XXX? verify
1579	esac
1580
1581	case "`/usr/sbin/lsattr -El proc0 -a type -F value`" in
1582	    PowerPC_POWER*) pp_aix_arch_std=ppc64;;
1583	    PowerPC*) pp_aix_arch_std=ppc;;
1584	    *) pp_aix_arch_std=unknown;;
1585	esac
1586}
1587
1588pp_aix_detect_os () {
1589        typeset r v
1590
1591        r=`uname -r`
1592        v=`uname -v`
1593        pp_aix_os=aix$v$r
1594}
1595
1596pp_aix_version_fix () {
1597    typeset v
1598    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'`
1599    if test x"$v" != x"$1"; then
1600        pp_warn "stripped version '$1' to '$v'"
1601    fi
1602    case $v in
1603        ""|*..*|.*|*.) pp_error "malformed '$1'"
1604                 echo "0.0.0.0";;
1605        *.*.*.*.*)
1606                 # 5 components are only valid for fileset updates, not base
1607                 # filesets (full packages). We trim 5+ components down to 4.
1608                 pp_warn "version '$1' has too many dots for AIX, truncating"
1609                 echo "$v" | cut -d. -f1-4;;
1610        *.*.*.*) echo "$v";;
1611        *.*.*) echo "$v.0";;
1612        *.*) echo "$v.0.0";;
1613        *) echo "$v.0.0.0";;
1614    esac
1615}
1616
1617pp_aix_select () {
1618	case "$1" in
1619	    -user) op="";;
1620	    -root) op="!";;
1621	    *) pp_die "pp_aix_select: bad argument";;
1622	esac
1623	#pp_debug awk '$5 '$op' /^\/(usr|opt)(\/|$)/ { print; }'
1624	#awk '$5 '$op' /^\/(usr|opt)(\/|$)/ { print; }'
1625	awk $op'($6 ~ /^\/usr\// || $6 ~ /^\/opt\//) { print; }'
1626}
1627
1628pp_aix_copy_root () {
1629    typeset t m o g f p st target
1630    while read t m o g f p st; do
1631        case "$t" in
1632           d) pp_create_dir_if_missing "$1${p%/}";;
1633           f) pp_add_transient_file "$1$p"
1634	      pp_verbose ln "$pp_destdir$p" "$pp_destdir$1$p" ||
1635		pp_error "can't link $p into $1";;
1636           *) pp_warn "pp_aix_copy_root: filetype $t not handled";;
1637        esac
1638    done
1639}
1640
1641
1642pp_aix_size () {
1643    typeset prefix t m o g f p st
1644
1645    prefix="$1"
1646    while read t m o g f p st; do
1647      case "$t" in f) du -a "$pp_destdir$p";; esac
1648    done | sed -e 's!/[^/]*$!!' | sort +1 |
1649    awk '{ if ($2 != d)
1650           { if (sz) print d,sz;
1651             d=$2; sz=0 }
1652           sz += $1; }
1653         END { if (sz) print d,sz }' |
1654    sed -n -e "s!^$pp_destdir!$prefix!p"
1655}
1656
1657pp_aix_list () {
1658    awk '{ print "." pfx $6; }' pfx="$1"
1659}
1660
1661pp_aix_make_liblpp () {
1662    typeset out dn fl f
1663
1664    out="$1"; shift
1665    dn=`dirname "$2"`
1666    fl=
1667    for f
1668    do
1669	case "$f" in "$dn/"*) fl="$fl `basename $f`" ;;
1670		     *) pp_die "liblpp name $f not in $dn/";; esac
1671    done
1672    (cd "$dn" && pp_verbose  ar -c -g -r "$out" $fl) || pp_error "ar error"
1673}
1674
1675pp_aix_make_script () {
1676    rm -f "$1"
1677    echo "#!/bin/sh" > "$1"
1678    cat >> "$1"
1679    echo "exit 0" >> "$1"
1680    chmod +x "$1"
1681}
1682
1683pp_aix_inventory () {
1684    typeset fileset t m o g f p st type
1685
1686    fileset="$1"
1687    while read t m o g f p st; do
1688      case "$p" in *:*) pp_error "path $p contains colon";; esac
1689      echo "$p:"
1690      case "$t" in
1691	f)   type=FILE;      defm=644 ;;
1692	s)   type=SYMLINK;   defm=777 ;;
1693	d)   type=DIRECTORY; defm=755 ;;
1694      esac
1695      echo " type = $type"
1696      echo " class = inventory,apply,$fileset"
1697      if test x"$m" = x"-"; then m="$defm"; fi
1698      if test x"$o" = x"-"; then o="root"; fi
1699      if test x"$g" = x"-"; then g="system"; fi
1700      echo " owner = $o"
1701      echo " group = $g"
1702
1703      case "$m" in ????)
1704	m=`echo $m|sed -e 's/^1/TCB,/' \
1705		       -e 's/^[23]/TCB,SGID,/' \
1706		       -e 's/^[45]/TCB,SUID,/' \
1707		       -e 's/^[67]/TCB,SUID,SGID,/'`;;  # vtx bit ignored
1708      esac
1709      echo " mode = $m"
1710      case "$t" in
1711	f) if test ! -f "$pp_destdir$p"; then
1712		pp_error "$p: missing file"
1713	   fi
1714	   case "$flags" in
1715	    *v*)
1716	      echo " size = VOLATILE"
1717	      echo " checksum = VOLATILE"
1718	      ;;
1719	    *)
1720	      if test -r "$pp_destdir$p"; then
1721	        echo " size = $size"
1722                pp_verbose  sum -r < "$pp_destdir$p" |
1723	      	  sed -e 's/.*/ checksum = "&"/'
1724	      fi
1725	      ;;
1726	   esac;;
1727	s)
1728	   echo " target = $st"
1729	   ;;
1730      esac
1731
1732      #-- Record ABI types seen
1733      case "$t" in
1734        f) if test -r "$pp_destdir$p"; then
1735	    case "`file "$pp_destdir$p"`" in
1736		*"executable (RISC System/6000)"*) abi=ppc;;
1737		*"64-bit XCOFF executable"*)       abi=ppc64;;
1738		*) abi=;;
1739	    esac
1740	    if test -n "$abi"; then
1741		pp_add_to_list pp_aix_abis_seen $abi
1742	    fi
1743	   fi;;
1744      esac
1745
1746    done
1747}
1748
1749pp_aix_depend ()
1750{
1751    if test -s "$1"; then
1752       pp_warn "aix dependencies not implemented"
1753    fi
1754}
1755
1756pp_aix_add_service () {
1757	typeset svc cmd_cmd cmd_arg f
1758	svc="$1"
1759
1760	pp_load_service_vars $svc
1761
1762	set -- $cmd
1763	cmd_cmd="$1"; shift
1764	cmd_arg="${pp_aix_mkssys_cmd_args:-$*}";
1765
1766	case "$stop_signal" in
1767		HUP) stop_signal=1;;
1768		INT) stop_signal=2;;
1769		QUIT) stop_signal=3;;
1770		KILL) stop_signal=9;;
1771		TERM) stop_signal=15;;
1772		USR1) stop_signal=30;;
1773		USR2) stop_signal=31;;
1774		"")
1775		  pp_error "%service $svc: stop_signal not set";;
1776		[a-zA-Z]*)
1777		  pp_error "%service $svc: bad stop_signal ($stop_signal)";;
1778	esac
1779
1780	test -z "$pidfile" || pp_error "aix requires empty pidfile (non daemon)"
1781
1782	pp_add_component run
1783	if test "$user" = "root"; then
1784	    uid=0
1785	else
1786            uid="\"\`/usr/bin/id -u $user\`\""
1787	fi
1788
1789
1790        #-- add command text to create/remove the service
1791	cat <<-. >> $pp_wrkdir/%post.$svc
1792svc=$svc
1793uid=0
1794cmd_cmd="$cmd_cmd"
1795cmd_arg="$cmd_arg"
1796stop_signal=$stop_signal
1797force_signal=9
1798srcgroup="$pp_aix_mkssys_group"
1799instances_allowed=${pp_aix_mkssys_instances_allowed:--Q}
1800
1801lssrc -s \$svc > /dev/null 2>&1
1802if [ \$? -eq 0 ]; then
1803  lssrc -s \$svc | grep "active" > /dev/null 2>&1
1804  if [ \$? -eq 0 ]; then
1805    stopsrc -s \$svc > /dev/null 2>&1
1806  fi
1807  rmsys -s \$svc > /dev/null 2>&1
1808fi
1809
1810mkssys -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
1811.
1812
1813        #-- add code to start the service on reboot
1814        ${pp_aix_init_services_after_install} &&
1815          cat <<-. >> $pp_wrkdir/%post.$svc
1816id=\`echo "\$svc" | cut -c1-14\`
1817mkitab "\$id:2:once:/usr/bin/startsrc -s \$svc" > /dev/null 2>&1
1818.
1819
1820	${pp_aix_start_services_after_install} &&
1821          cat <<-. >> $pp_wrkdir/%post.$svc
1822startsrc -s \$svc
1823.
1824
1825if [ -f "$pp_wrkdir/%post.run" ];then
1826    cat $pp_wrkdir/%post.run >> $pp_wrkdir/%post.$svc
1827fi
1828mv $pp_wrkdir/%post.$svc $pp_wrkdir/%post.run
1829
1830
1831        ${pp_aix_init_services_after_install} &&
1832           pp_prepend $pp_wrkdir/%preun.$svc <<-.
1833rmitab `echo "$svc" | cut -c1-14` > /dev/null 2>&1
1834.
1835	pp_prepend $pp_wrkdir/%preun.$svc <<-.
1836stopsrc -s $svc >/dev/null 2>&1
1837rmssys -s $svc
1838.
1839
1840if [ -f "$pp_wrkdir/%preun.run" ];then
1841    cat $pp_wrkdir/%preun.run >> $pp_wrkdir/%preun.$svc
1842fi
1843mv $pp_wrkdir/%preun.$svc $pp_wrkdir/%preun.run
1844}
1845
1846pp_backend_aix () {
1847        typeset briefex instuser instroot svc cmp outbff
1848        typeset user_wrkdir root_wrkdir
1849        typeset user_files root_files
1850
1851	test -n "$pp_destdir" ||
1852	   pp_error "AIX backend requires the '--destdir' option"
1853
1854	instuser="/usr/lpp/$name"
1855	instroot="$instuser/inst_root"
1856	pp_aix_bff_name=${pp_aix_bff_name:-$name}
1857
1858	# Here is the component mapping:
1859	#  run -> $pp_aix_bff_name.rte ('Run time environment')
1860	#  doc -> $pp_aix_bff_name.doc (non-standard)
1861	#  dev -> $pp_aix_bff_name.adt ('Application developer toolkit')
1862	#  dbg -> $pp_aix_bff_name.diag ('Diagnostics')
1863
1864	test `echo "$summary" | wc -c ` -gt 40 && pp_error "\$summary too long"
1865
1866	user_wrkdir=$pp_wrkdir/u
1867	root_wrkdir=$pp_wrkdir/r
1868	pp_verbose  rm -rf $user_wrkdir $root_wrkdir
1869	pp_verbose  mkdir -p $user_wrkdir $root_wrkdir
1870
1871	for svc in $pp_services .; do
1872	    test . = "$svc" && continue
1873            pp_aix_add_service $svc
1874	done
1875
1876        {
1877	  echo "4 $pp_aix_arch I $name {"
1878
1879	  for cmp in $pp_components; do
1880	    case "$cmp" in
1881		run) ex=rte  briefex="runtime";;
1882		doc) ex=doc  briefex="documentation";;
1883		dev) ex=adt  briefex="developer toolkit";;
1884		dbg) ex=diag briefex="diagnostics";;
1885	    esac
1886
1887	    user_files=$pp_wrkdir/%files.$cmp.u
1888	    root_files=$pp_wrkdir/%files.$cmp.r
1889
1890	    pp_aix_select -user < $pp_wrkdir/%files.$cmp > $user_files
1891	    pp_aix_select -root < $pp_wrkdir/%files.$cmp > $root_files
1892
1893            # Default to USR only unless there are root files,
1894            # or a post/pre/check script associated
1895	    content=U
1896            if test -s $root_files \
1897                    -o -s $pp_wrkdir/%pre.$cmp \
1898                    -o -s $pp_wrkdir/%post.$cmp \
1899                    -o -s $pp_wrkdir/%preun.$cmp \
1900                    -o -s $pp_wrkdir/%postun.$cmp \
1901                    -o -s $pp_wrkdir/%check.$cmp
1902            then
1903                content=B
1904            fi
1905
1906            if $pp_opt_debug; then
1907                echo "$cmp USER %files:"
1908                cat $user_files
1909                echo "$cmp ROOT %files:"
1910                cat $root_files
1911            fi >&2
1912
1913	    bosboot=N; pp_contains_any "$pp_aix_bosboot" $cmp && bosboot=b
1914
1915            echo $pp_aix_bff_name.$ex \
1916             `[ $pp_aix_version ] && pp_aix_version_fix $pp_aix_version || pp_aix_version_fix "$version"` \
1917	         1 $bosboot $content \
1918	         $pp_aix_lang "$summary $briefex"
1919	    echo "["
1920
1921	    pp_aix_depend $pp_wrkdir/%depend.$cmp
1922
1923	    echo "%"
1924
1925	    # generate per-directory size information
1926	    pp_aix_size < $user_files
1927	    pp_aix_size $instroot < $root_files
1928
1929	    pp_aix_list            < $user_files  > $user_wrkdir/$pp_aix_bff_name.$ex.al
1930	    pp_aix_list $instroot  < $root_files >> $user_wrkdir/$pp_aix_bff_name.$ex.al
1931	    pp_aix_list            < $root_files  > $root_wrkdir/$pp_aix_bff_name.$ex.al
1932
1933            if $pp_opt_debug; then
1934                echo "$cmp USER $pp_aix_bff_name.$ex.al:"
1935                cat $user_wrkdir/$pp_aix_bff_name.$ex.al
1936                echo "$cmp ROOT $pp_aix_bff_name.$ex.al:"
1937                cat $root_wrkdir/$pp_aix_bff_name.$ex.al
1938            fi >&2
1939
1940	    pp_aix_inventory $pp_aix_bff_name.$ex < $user_files \
1941                                       > $user_wrkdir/$pp_aix_bff_name.$ex.inventory
1942	    pp_aix_inventory $pp_aix_bff_name.$ex < $root_files \
1943                                       > $root_wrkdir/$pp_aix_bff_name.$ex.inventory
1944
1945            if $pp_opt_debug; then
1946                pp_debug "$cmp USER $pp_aix_bff_name.$ex.inventory:"
1947                cat $user_wrkdir/$pp_aix_bff_name.$ex.inventory
1948                pp_debug "$cmp ROOT $pp_aix_bff_name.$ex.inventory:"
1949                cat $root_wrkdir/$pp_aix_bff_name.$ex.inventory
1950            fi >&2
1951
1952	    if test x"" != x"${pp_aix_copyright:-$copyright}"; then
1953	        echo "${pp_aix_copyright:-$copyright}" > $user_wrkdir/$pp_aix_bff_name.$ex.copyright
1954	        echo "${pp_aix_copyright:-$copyright}" > $root_wrkdir/$pp_aix_bff_name.$ex.copyright
1955	    fi
1956
1957	    #-- assume that post/pre uninstall scripts only make
1958	    #   sense when installed in a root context
1959
1960	    if test -r $pp_wrkdir/%pre.$cmp; then
1961			pp_aix_make_script $user_wrkdir/$pp_aix_bff_name.$ex.pre_i \
1962                < $pp_wrkdir/%pre.$cmp
1963	    fi
1964
1965	    if test -r $pp_wrkdir/%post.$cmp; then
1966		pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.post_i \
1967			< $pp_wrkdir/%post.$cmp
1968	    fi
1969
1970	    if test -r $pp_wrkdir/%preun.$cmp; then
1971		pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.unpost_i \
1972			< $pp_wrkdir/%preun.$cmp
1973	    fi
1974
1975	    if test -r $pp_wrkdir/%postun.$cmp; then
1976		pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.unpre_i \
1977			< $pp_wrkdir/%postun.$cmp
1978	    fi
1979
1980	    # remove empty files
1981	    for f in $user_wrkdir/$pp_aix_bff_name.$ex.* $root_wrkdir/$pp_aix_bff_name.$ex.*; do
1982	      if test ! -s "$f"; then
1983                pp_debug "removing empty $f"
1984                rm -f "$f"
1985              fi
1986	    done
1987
1988	    # copy/link the root files so we can do an easy backup later
1989	    pp_aix_copy_root $instroot < $root_files
1990
1991	    echo "%"
1992	    echo "]"
1993	  done
1994	  echo "}"
1995	} > $pp_wrkdir/lpp_name
1996
1997        if $pp_opt_debug; then
1998            echo "/lpp_name :"
1999            cat $pp_wrkdir/lpp_name
2000        fi >&2
2001
2002        #-- copy the /lpp_name file to the destdir
2003        pp_add_transient_file /lpp_name
2004        cp $pp_wrkdir/lpp_name $pp_destdir/lpp_name
2005
2006        #-- copy the liblpp.a files under destdir for packaging
2007	(cd $user_wrkdir && pp_verbose  ar -c -g -r liblpp.a $name.*) ||
2008		pp_error "ar error"
2009	if test -s $user_wrkdir/liblpp.a; then
2010           pp_add_transient_file $instuser/liblpp.a
2011	   pp_verbose cp $user_wrkdir/liblpp.a $pp_destdir$instuser/liblpp.a ||
2012		pp_error "cannot create user liblpp.a"
2013	fi
2014	(cd $root_wrkdir && pp_verbose  ar -c -g -r liblpp.a $name.*) ||
2015		pp_error "ar error"
2016	if test -s $root_wrkdir/liblpp.a; then
2017           pp_add_transient_file $instroot/liblpp.a
2018	   pp_verbose cp $root_wrkdir/liblpp.a $pp_destdir$instroot/liblpp.a ||
2019		pp_error "cannot create root liblpp.a"
2020	fi
2021
2022        { echo ./lpp_name
2023	  test -s $user_wrkdir/liblpp.a && echo .$instuser/liblpp.a
2024	  test -s $root_wrkdir/liblpp.a && echo .$instroot/liblpp.a
2025	  cat $user_wrkdir/$name.*.al   # includes the relocated root files!
2026	} > $pp_wrkdir/bff.list
2027
2028	if test -n "$pp_aix_abis_seen" -a x"$pp_aix_arch_std" = x"auto"; then
2029	    case "$pp_aix_abis_seen" in
2030		"ppc ppc64"|"ppc64 ppc")
2031		    pp_aix_arch_std=ppc64
2032		    ;;
2033		ppc|ppc64)
2034		    pp_aix_arch_std=$pp_aix_abis_seen
2035		    ;;
2036		*" "*)
2037		    pp_warn "multiple architectures detected: $pp_aix_abis_seen"
2038		    pp_aix_arch_std=unknown
2039		    ;;
2040		"")
2041		    pp_warn "no binary executables detected; using noarch"
2042		    pp_aix_arch_std=noarch
2043		    ;;
2044		*)
2045		    pp_warn "unknown architecture detected $pp_aix_abis_seen"
2046		    pp_aix_arch_std=$pp_aix_abis_seen
2047		    ;;
2048	    esac
2049	fi
2050
2051	. $pp_wrkdir/%fixup
2052
2053        outbff=`pp_backend_aix_names`
2054        pp_debug "creating: $pp_wrkdir/$outbff"
2055	(cd $pp_destdir && pp_verbose  /usr/sbin/backup -i -q -p -f -) \
2056          < $pp_wrkdir/bff.list \
2057	  > $pp_wrkdir/$outbff || pp_error "backup failed"
2058        $pp_aix_sudo /usr/sbin/installp -l -d $pp_wrkdir/$outbff
2059}
2060
2061pp_backend_aix_cleanup () {
2062    :
2063}
2064
2065pp_backend_aix_names () {
2066    echo "$name.`[ $pp_aix_version ] && pp_aix_version_fix $pp_aix_version || pp_aix_version_fix "$version"`.bff"
2067}
2068
2069pp_backend_aix_install_script () {
2070	typeset pkgname platform
2071        #
2072        # The script should take a first argument being the
2073        # operation; further arguments refer to components or services
2074        #
2075        # list-components           -- lists components in the pkg
2076        # install component...      -- installs the components
2077        # uninstall component...    -- uninstalles the components
2078        # list-services             -- lists the services in the pkg
2079        # start service...          -- starts the name service
2080        # stop service...           -- stops the named services
2081        # print-platform            -- prints the platform group
2082        #
2083        pkgname="`pp_backend_aix_names`"
2084	platform="`pp_backend_aix_probe`"   # XXX should be derived from files
2085
2086        fsets=
2087        for cmp in $pp_components; do
2088	    case "$cmp" in
2089		run) ex=rte;;
2090		doc) ex=doc;;
2091		dev) ex=adt;;
2092		dbg) ex=diag;;
2093	    esac
2094            fsets="$fsets $name.$ex"
2095        done
2096
2097        echo '#!/bin/sh'
2098        pp_install_script_common
2099
2100        cat <<-.
2101
2102            cpt_to_fileset () {
2103                test x"\$*" = x"all" &&
2104                    set -- $pp_components
2105                for cpt
2106                do
2107                    case "\$cpt" in
2108                        run) echo "$name.rte";;
2109                        doc) echo "$name.doc";;
2110                        dev) echo "$name.adt";;
2111                        dbg) echo "$name.diag";;
2112                        *) usage;;
2113                    esac
2114                done
2115            }
2116
2117	    test \$# -eq 0 && usage
2118            op="\$1"; shift
2119
2120            case "\$op" in
2121                list-components)
2122                    test \$# -eq 0 || usage \$op
2123                    echo "$pp_components"
2124                    ;;
2125                list-services)
2126                    test \$# -eq 0 || usage \$op
2127                    echo "$pp_services"
2128                    ;;
2129                list-files)
2130                    test \$# -ge 1 || usage \$op
2131                    echo \${PP_PKGDESTDIR:-.}/$pkgname
2132                    ;;
2133                install)
2134                    test \$# -ge 1 || usage \$op
2135                    verbose /usr/sbin/installp -acX -V0 -F \
2136                        -d \${PP_PKGDESTDIR:-.}/$pkgname \
2137                        \`cpt_to_fileset "\$@"\`
2138                    ;;
2139                uninstall)
2140                    test \$# -ge 1 || usage \$op
2141                    verbose /usr/sbin/installp -u -e/dev/null \
2142			-V0 \`cpt_to_fileset "\$@"\`
2143                    ;;
2144                start|stop)
2145                    test \$# -ge 1 || usage \$op
2146                    ec=0
2147                    for svc
2148                    do
2149                        verbose \${op}src -s \$svc || ec=1
2150                    done
2151                    exit \$ec
2152                    ;;
2153                print-platform)
2154                    echo "$platform"
2155		    ;;
2156                *)
2157                    usage;;
2158            esac
2159.
2160}
2161
2162pp_backend_aix_init_svc_vars () {
2163    :
2164}
2165
2166pp_backend_aix_probe () {
2167	echo "${pp_aix_os}-${pp_aix_arch_std}"
2168}
2169
2170pp_backend_aix_vas_platforms () {
2171    case "${pp_aix_arch_std}" in
2172	ppc*)	:;;
2173	*)	pp_die "unknown architecture ${pp_aix_arch_std}";;
2174    esac
2175    case "${pp_aix_os}" in
2176	aix43)	echo "aix-43";;
2177	aix51)	echo "aix-51 aix-43";;
2178	aix52)	echo "aix-51 aix-43";;
2179	aix53)	echo "aix-53 aix-51 aix-43";;
2180	aix61)	echo "aix-53 aix-51 aix-43";;
2181	*)	pp_die "unknown system ${pp_aix_os}";;
2182    esac
2183}
2184pp_backend_aix_function () {
2185    case "$1" in
2186    pp_mkgroup) cat <<'.';;
2187            /usr/sbin/lsgroup "$1" >/dev/null &&
2188		return 0
2189	    echo "Creating group $1"
2190            /usr/bin/mkgroup -A "$1"
2191.
2192    pp_mkuser:depends) echo pp_mkgroup;;
2193    pp_mkuser) cat <<'.';;
2194            /usr/sbin/lsuser "$1" >/dev/null &&
2195	        return 0
2196	    pp_mkgroup "${2:-$1}" || return 1
2197	    echo "Creating user $1"
2198	    /usr/bin/mkuser \
2199	        login=false \
2200	        rlogin=false \
2201		account_locked=true \
2202		home="${3:-/nohome.$1}" \
2203		pgrp="${2:-$1}" \
2204		"$1"
2205.
2206    pp_havelib) cat <<'.';;
2207            case "$2" in
2208                "")    pp_tmp_name="lib$1.so";;
2209                *.*.*) pp_tmp_name="lib$1.so.$2";;
2210                *.*)   pp_tmp_name="lib$1.so.$2.0";;
2211                *)     pp_tmp_name="lib$1.so.$2";;
2212            esac
2213            for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
2214                test -r "$pp_tmp_dir/$pp_tmp_name" -a \
2215		    -r "$pp_tmp_dir/lib$1.so" && return 0
2216            done
2217            return 1
2218.
2219    *) false;;
2220    esac
2221}
2222
2223pp_platforms="$pp_platforms sd"
2224
2225pp_backend_sd_detect () {
2226    test x"$1" = x"HP-UX"
2227}
2228
2229pp_backend_sd_init () {
2230    pp_sd_sudo=
2231    pp_sd_startlevels=2
2232    pp_sd_stoplevels=auto
2233    pp_sd_config_file=
2234    pp_sd_vendor=
2235    pp_sd_vendor_tag=Quest
2236    pp_sd_default_start=1           # config_file default start value
2237
2238    pp_readlink_fn=pp_ls_readlink   # HPUX has no readlink
2239    pp_shlib_suffix='.sl'           # .so on most other platforms
2240
2241    pp_sd_detect_os
2242}
2243
2244pp_sd_detect_os () {
2245    typeset revision
2246
2247    revision=`uname -r`
2248    pp_sd_os="${revision#?.}"
2249    test -z "$pp_sd_os" &&
2250        pp_warn "cannot detect OS version"
2251    pp_sd_os_std="hpux`echo $pp_sd_os | tr -d .`"
2252
2253    case "`uname -m`" in
2254	9000/[678]??) pp_sd_arch_std=hppa;;
2255	ia64) pp_sd_arch_std=ia64;;
2256	*) pp_sd_arch_std=unknown;;
2257    esac
2258}
2259
2260pp_sd_write_files () {
2261    typeset t m o g f p st line dm
2262    while read t m o g f p st; do
2263        line="                file"
2264        case "$f" in *v*) line="$line -v";; esac    # FIXME for uninstall
2265	case ${pp_sd_os} in
2266	    10.*)
2267		case $t in
2268		    f) dm=644;;
2269		    d) p=${p%/}; dm=755;;
2270		esac
2271		;;
2272	    *)
2273		case $t in
2274		    f) dm=644;;
2275		    d) line="$line -t d"; p=${p%/}; dm=755;;
2276		    s) line="$line -t s";;
2277		esac
2278		;;
2279	esac
2280
2281        test x"$o" = x"-" && o=root
2282        test x"$g" = x"-" && g=sys
2283        test x"$m" = x"-" && m=$dm
2284
2285        case $t in
2286            s)
2287		# swpackage will make unqualified links relative to the
2288		# current working (source) directory, not the destination;
2289		# we need to qualify them to prevent this.
2290		case "$st" in
2291		    [!/]*) st="`dirname \"$p\"`/$st";;
2292		esac
2293		echo "$line -o $o -g $g -m $m $st $p"
2294		;;
2295            *)
2296		echo "$line -o $o -g $g -m $m $pp_destdir$p $p"
2297		;;
2298        esac
2299
2300    done
2301}
2302
2303pp_sd_service_group_script () {
2304    typeset grp svcs scriptpath out
2305    grp="$1"
2306    svcs="$2"
2307    scriptpath="/sbin/init.d/$grp"
2308    out="$pp_destdir$scriptpath"
2309
2310    pp_add_file_if_missing $scriptpath run 755 || return 0
2311
2312    cat <<-. > $out
2313	#!/sbin/sh
2314	# generated by pp $pp_version
2315	svcs="$svcs"
2316.
2317
2318    cat <<-'.' >> $out
2319	#-- starts services in order.. stops them all if any break
2320	pp_start () {
2321	    undo=
2322	    for svc in \$svcs; do
2323	        /sbin/init.d/\$svc start
2324	        case \$? in
2325	          0|4)
2326	            undo="\$svc \$undo"
2327	            ;;
2328	          *)
2329	            if test -n "\$undo"; then
2330	                for svc in \$undo; do
2331	                    /sbin/init.d/\$svc stop
2332	                done
2333	                return 1
2334	            fi
2335	            ;;
2336	        esac
2337	    done
2338	    return 0
2339	}
2340
2341	#-- stops services in reverse
2342	pp_stop () {
2343	    reverse=
2344	    for svc in \$svcs; do
2345	        reverse="\$svc \$reverse"
2346	    done
2347	    rc=0
2348	    for svc in \$reverse; do
2349	        /sbin/init.d/\$svc stop || rc=\$?
2350	    done
2351	    return \$rc
2352        }
2353
2354	case \$1 in
2355	    start_msg) echo "Starting \$svcs";;
2356	    stop_msg)  echo "Stopping \$svcs";;
2357	    start)     pp_start;;
2358	    stop)      pp_stop;;
2359	    *)	       echo "usage: \$0 {start|stop|start_msg|stop_msg}"
2360	               exit 1;;
2361	esac
2362.
2363}
2364
2365pp_sd_service_script () {
2366    typeset svc config_file config_value scriptpath out
2367
2368    svc="$1"
2369    scriptpath="/sbin/init.d/$svc"
2370
2371    config_file=${pp_sd_config_file:-/etc/rc.config.d/$svc}
2372    sd_config_var=`echo run-$svc | tr '[a-z]-' '[A-Z]_'`
2373    sd_config_value=${pp_sd_default_start:-0}
2374    pp_load_service_vars "$svc"
2375
2376    test -n "$user" -a x"$user" != x"root" &&
2377        cmd="SHELL=/usr/bin/sh /usr/bin/su $user -c \"exec `echo $cmd | sed -e 's,[$\\\`],\\&,g'`\""
2378    if test -z "$pidfile"; then
2379        pidfile="/var/run/$svc.pid"
2380        cmd="$cmd & echo \$! > \$pidfile"
2381    fi
2382
2383    pp_debug "config file is $config_file"
2384
2385    pp_add_file_if_missing $scriptpath run 755
2386    pp_add_file_if_missing $config_file run 644 v
2387
2388    cat <<-. >> $pp_destdir$config_file
2389
2390	# Controls whether the $svc service is started
2391	$sd_config_var=$sd_config_value
2392.
2393
2394    if test ! -f $pp_destdir$scriptpath; then
2395    cat <<-. > $pp_destdir$scriptpath
2396	#!/sbin/sh
2397	# generated by pp $pp_version
2398
2399	svc="$svc"
2400	pidfile="$pidfile"
2401	config_file="$config_file"
2402
2403	pp_start () {
2404	    $cmd
2405	}
2406
2407	pp_disabled () {
2408	    test \${$sd_config_var:-0} -eq 0
2409	}
2410
2411	pp_stop () {
2412	    if test ! -s "\$pidfile"; then
2413	        echo "Unable to stop \$svc (no pid file)"
2414	        return 1
2415	    else
2416	        read pid < "\$pidfile"
2417	        if kill -0 "\$pid" 2>/dev/null; then
2418	            if kill -${stop_signal:-TERM} "\$pid"; then
2419	                rm -f "\$pidfile"
2420	                return 0
2421	            else
2422	                echo "Unable to stop \$svc"
2423	                return 1
2424	            fi
2425	        else
2426	            rm -f "\$pidfile"
2427	            return 0
2428	        fi
2429	    fi
2430	}
2431
2432	pp_running () {
2433	    if test ! -s "\$pidfile"; then
2434	        return 1
2435	    else
2436	        read pid < "\$pidfile"
2437	        kill -0 "\$pid" 2>/dev/null
2438	    fi
2439	}
2440
2441	case \$1 in
2442	    start_msg) echo "Starting the \$svc service";;
2443	    stop_msg)  echo "Stopping the \$svc service";;
2444	    start)
2445	            if test -f "\$config_file"; then
2446	                . \$config_file
2447	            fi
2448	            if pp_disabled; then
2449	                exit 2
2450	            elif pp_running; then
2451	                echo "\$svc already running";
2452	                exit 0
2453	            elif pp_start; then
2454	                echo "\$svc started";
2455	                # rc(1M) says we should exit 4, but nobody expects it!
2456	                exit 0
2457	            else
2458	                exit 1
2459	            fi;;
2460	    stop)   if pp_stop; then
2461	                echo "\$svc stopped";
2462	                exit 0
2463	            else
2464	                exit 1
2465	            fi;;
2466	    *) echo "usage: \$0 {start|stop|start_msg|stop_msg}"
2467	       exit 1;;
2468	esac
2469.
2470    fi
2471}
2472
2473pp_sd_make_service () {
2474        typeset level startpriority stoppriority startlevels stoplevels
2475        typeset svc svcvar symtype
2476
2477        svc="$1"
2478	svcvar=`pp_makevar $svc`
2479
2480	case ${pp_sd_os} in
2481	    10.*) symtype="file";;
2482	    *) symtype="file -t s";;
2483	esac
2484
2485        # TODO: Figure out why this check is here
2486        #-- don't do anything if the script exists
2487        #if test -s "$pp_destdir/sbin/init.d/$svc"; then
2488        #    pp_error "$pp_destdir/sbin/init.d/$svc exists"
2489        #    return
2490        #fi
2491
2492        # symlink the script, depending on the priorities chosen
2493        eval startpriority='${pp_sd_startpriority_'$svcvar'}'
2494        eval stoppriority='${pp_sd_stoppriority_'$svcvar'}'
2495        test -z "$startpriority" && startpriority="${pp_sd_startpriority:-50}"
2496        test -z "$stoppriority" && stoppriority="${pp_sd_stoppriority:-50}"
2497
2498        eval startlevels='${pp_sd_startlevels_'$svcvar'}'
2499        test -z "$startlevels" && startlevels="$pp_sd_startlevels"
2500
2501        eval stoplevels='${pp_sd_stoplevels_'$svcvar'}'
2502        test -z "$stoplevels" && stoplevels="$pp_sd_stoplevels"
2503
2504        # create the script and config file
2505        pp_sd_service_script $svc
2506
2507        # fix the priority up
2508        case "$startpriority" in
2509            ???) :;;
2510            ??) startpriority=0$startpriority;;
2511            ?) startpriority=00$startpriority;;
2512        esac
2513        case "$stoppriority" in
2514            ???) :;;
2515            ??) stoppriority=0$stoppriority;;
2516            ?) stoppriority=00$stoppriority;;
2517        esac
2518
2519        if test x"$stoplevels" = x"auto"; then
2520            stoplevels=
2521            test -z "$startlevels" || for level in $startlevels; do
2522                stoplevels="$stoplevels `expr $level - 1`"
2523            done
2524        fi
2525
2526        # create the symlinks
2527        test -z "$startlevels" || for level in $startlevels; do
2528            echo "                ${symtype}" \
2529                    "/sbin/init.d/$svc" \
2530                    "/sbin/rc$level.d/S$startpriority$svc"
2531        done
2532        test -z "$stoplevels" || for level in $stoplevels; do
2533            echo "                ${symtype}" \
2534                    "/sbin/init.d/$svc" \
2535                    "/sbin/rc$level.d/K$stoppriority$svc"
2536        done
2537}
2538
2539pp_sd_control () {
2540    typeset ctrl script
2541    typeset cpt
2542
2543    ctrl="$1"; shift
2544    cpt="$1"; shift
2545    script="$pp_wrkdir/control.$ctrl.$cpt"
2546    cat <<. >$script
2547.
2548    cat "$@" >> $script
2549    echo "exit 0" >> $script
2550    /usr/bin/chmod +x $script
2551    echo "                $ctrl $script"
2552}
2553
2554pp_sd_depend () {
2555    typeset _name _vers
2556    while read _name _vers; do
2557	case "$_name" in ""| "#"*) continue ;; esac
2558	echo "                prerequisites $_name ${_vers:+r>= $_vers}"
2559    done
2560}
2561
2562pp_sd_conflict () {
2563    typeset _name _vers
2564    while read _name _vers; do
2565	case "$_name" in ""| "#"*) continue ;; esac
2566	echo "                exrequisites $_name ${_vers:+r>= $_vers}"
2567    done
2568}
2569
2570pp_backend_sd () {
2571    typeset psf cpt svc outfile release swp_flags
2572
2573    psf=$pp_wrkdir/psf
2574    release="?.${pp_sd_os%.[0-9][0-9]}.*"
2575
2576    echo "depot" > $psf
2577    echo "layout_version 1.0" >>$psf
2578
2579    #-- vendor
2580    cat <<. >>$psf
2581        vendor
2582            tag             $pp_sd_vendor_tag
2583            title           "${pp_sd_vendor:-$vendor}"
2584        end
2585
2586        product
2587            tag             $name
2588            revision        $version
2589            vendor_tag      $pp_sd_vendor_tag
2590            is_patch        false
2591            title           "$summary"
2592            copyright       "$copyright"
2593            machine_type    *
2594            os_name         HP-UX
2595            os_release      $release
2596            os_version      ?
2597            directory       /
2598            is_locatable    false
2599.
2600    test -n "$description" \
2601        && echo $description > $pp_wrkdir/description \
2602        && cat <<. >> $psf
2603            description     < $pp_wrkdir/description
2604.
2605
2606    # make convenience service groups
2607    if test -n "$pp_service_groups"; then
2608	for grp in $pp_service_groups; do
2609	    pp_sd_service_group_script \
2610		$grp "`pp_service_get_svc_group $grp`"
2611	done
2612    fi
2613
2614    for cpt in $pp_components; do
2615        cat <<. >>$psf
2616            fileset
2617                tag             ${pp_sd_fileset_tag:-$cpt}
2618                title           "${summary:-cpt}"
2619                revision        $version
2620.
2621        test -s $pp_wrkdir/%depend.$cpt &&
2622              pp_sd_depend < $pp_wrkdir/%depend.$cpt >> $psf
2623        test -s $pp_wrkdir/%conflict.$cpt &&
2624              pp_sd_conflict < $pp_wrkdir/%conflict.$cpt >> $psf
2625
2626	#-- make sure services are shut down during uninstall
2627        if test $cpt = run -a -n "$pp_services"; then
2628            for svc in $pp_services; do
2629                pp_prepend $pp_wrkdir/%preun.$cpt <<-.
2630			/sbin/init.d/$svc stop
2631.
2632            done
2633        fi
2634
2635        #-- we put the post/preun code into configure/unconfigure
2636        # and not postinstall/preremove, because configure/unconfigure
2637        # scripts are run on the hosts where the package is installed,
2638        # not loaded (a subtle difference).
2639        test -s $pp_wrkdir/%pre.$cpt &&
2640            pp_sd_control checkinstall $cpt $pp_wrkdir/%pre.$cpt >> $psf
2641        test -s $pp_wrkdir/%post.$cpt &&
2642            pp_sd_control configure $cpt $pp_wrkdir/%post.$cpt >> $psf
2643        test -s $pp_wrkdir/%preun.$cpt &&
2644            pp_sd_control unconfigure $cpt $pp_wrkdir/%preun.$cpt >> $psf
2645        test -s $pp_wrkdir/%postun.$cpt &&
2646            pp_sd_control postremove $cpt $pp_wrkdir/%postun.$cpt >> $psf
2647        test -s $pp_wrkdir/%check.$cpt &&
2648            pp_sd_control checkinstall $cpt $pp_wrkdir/%check.$cpt >> $psf
2649
2650        if test $cpt = run -a -n "$pp_services"; then
2651            for svc in $pp_services; do
2652                #-- service names are 10 chars max on hpux
2653                case "$svc" in ???????????*)
2654                    pp_warn "service name '$svc' is too long for hpux";;
2655                esac
2656                pp_sd_make_service $svc >> $psf
2657            done
2658            #pp_sd_make_service_config
2659        fi
2660
2661        pp_sd_write_files < $pp_wrkdir/%files.$cpt >> $psf
2662
2663        #-- end fileset clause
2664        cat <<. >>$psf
2665            end
2666.
2667
2668    done
2669
2670    #-- end product clause
2671    cat <<. >>$psf
2672        end
2673.
2674
2675    $pp_opt_debug && cat $psf >&2
2676
2677    test -s $pp_wrkdir/%fixup && . $pp_wrkdir/%fixup
2678
2679    outfile=`pp_backend_sd_names`
2680    case ${pp_sd_os} in
2681	10.*)
2682	    swp_flags="-x target_type=tape"
2683	    ;;
2684	*)
2685	    swp_flags="-x media_type=tape"
2686	    ;;
2687    esac
2688    if pp_verbose ${pp_sd_sudo} /usr/sbin/swpackage -s $psf $swp_flags \
2689        @ $pp_wrkdir/$outfile
2690    then
2691        pp_verbose ${pp_sd_sudo} /usr/sbin/swlist -l file -s $pp_wrkdir/$outfile
2692    else
2693        pp_error "swpackage failed"
2694    fi
2695}
2696
2697pp_backend_sd_cleanup () {
2698    :
2699}
2700
2701pp_backend_sd_names () {
2702    echo "$name-$version.$pp_sd_arch_std.depot"
2703}
2704
2705pp_backend_sd_install_script () {
2706    typeset pkgname platform
2707
2708    pkgname=`pp_backend_sd_names`
2709    platform="`pp_backend_sd_probe`"
2710
2711    echo "#!/bin/sh"
2712    pp_install_script_common
2713    cat <<.
2714
2715        cpt_to_tags () {
2716            test x"\$*" = x"all" && set -- $pp_components
2717            for cpt
2718            do
2719                echo "$name.\$cpt"
2720            done
2721        }
2722
2723        test \$# -eq 0 && usage
2724        op="\$1"; shift
2725
2726        case "\$op" in
2727            list-components)
2728                test \$# -eq 0 || usage \$op
2729                echo "$pp_components"
2730                ;;
2731            list-services)
2732                test \$# -eq 0 || usage \$op
2733                echo "$pp_services"
2734                ;;
2735            list-files)
2736                test \$# -ge 1 || usage \$op
2737                echo \${PP_PKGDESTDIR:-.}/$pkgname
2738                ;;
2739            install)
2740                test \$# -ge 1 || usage \$op
2741                verbose /usr/sbin/swinstall -x verbose=0 \
2742                    -s \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \
2743                    \`cpt_to_tags "\$@"\`
2744                ;;
2745            uninstall)
2746                test \$# -ge 1 || usage \$op
2747                verbose /usr/sbin/swremove -x verbose=0 \
2748                    \`cpt_to_tags "\$@"\`
2749                ;;
2750            start|stop)
2751                test \$# -ge 1 || usage \$op
2752                ec=0
2753                for svc
2754                do
2755                    verbose /sbin/init.d/\$svc \$op
2756                    [ \$? -eq 4 -o \$? -eq 0 ] || ec=1
2757                done
2758                exit \$ec
2759                ;;
2760            print-platform)
2761		echo "$platform"
2762		;;
2763            *)
2764                usage
2765                ;;
2766        esac
2767.
2768}
2769
2770pp_backend_sd_probe () {
2771    echo "${pp_sd_os_std}-${pp_sd_arch_std}"
2772}
2773
2774pp_backend_sd_vas_platforms () {
2775    case "`pp_backend_sd_probe`" in
2776	hpux*-hppa) echo hpux-pa;;
2777	hpux*-ia64) echo hpux-ia64 hpux-pa;;
2778	*)	    pp_die "unknown system `pp_backend_sd_probe`";;
2779    esac
2780}
2781
2782pp_backend_sd_init_svc_vars () {
2783    :
2784}
2785pp_backend_sd_function () {
2786    case "$1" in
2787        pp_mkgroup) cat <<'.';;
2788	    /usr/sbin/groupmod "$1" 2>/dev/null ||
2789		/usr/sbin/groupadd "$1"
2790.
2791        pp_mkuser:depends) echo pp_mkgroup;;
2792        pp_mkuser) cat <<'.';;
2793	    pp_mkgroup "${2:-$1}" || return 1
2794	    /usr/sbin/useradd \
2795		-g "${2:-$1}" \
2796		-d "${3:-/nonexistent}" \
2797		-s "${4:-/bin/false}" \
2798		"$1"
2799.
2800        pp_havelib) cat <<'.';;
2801            for pp_tmp_dir in `echo /usr/lib${3:+:$3} | tr : ' '`; do
2802                test -r "$pp_tmp_dir/lib$1${2:+.$2}.sl" && return 0
2803            done
2804            return 1
2805.
2806        *) false;;
2807    esac
2808}
2809
2810pp_platforms="$pp_platforms solaris"
2811
2812pp_backend_solaris_detect () {
2813	test x"$1" = x"SunOS"
2814}
2815
2816pp_backend_solaris_init () {
2817	pp_solaris_category=
2818	pp_solaris_istates="s S 1 2 3"	# run-states when install is ok
2819	pp_solaris_rstates="s S 1 2 3"	# run-states when remove is ok
2820	pp_solaris_maxinst=
2821	pp_solaris_vendor=
2822	pp_solaris_pstamp=
2823	pp_solaris_copyright=
2824	pp_solaris_name=
2825	pp_solaris_desc=
2826	pp_solaris_package_arch=auto
2827
2828        pp_solaris_detect_os
2829        pp_solaris_detect_arch
2830
2831        pp_solaris_init_svc
2832
2833        #-- readlink not reliably available on Solaris
2834	pp_readlink_fn=pp_ls_readlink
2835}
2836
2837pp_solaris_detect_os () {
2838        typeset osrel
2839
2840        osrel=`/usr/bin/uname -r`
2841        case "$osrel" in
2842	    5.[0-6])	pp_solaris_os="sol2${osrel#5.}";;
2843	    5.*)        pp_solaris_os="sol${osrel#5.}";;
2844        esac
2845        test -z "$pp_solaris_os" &&
2846             pp_warn "can't determine OS suffix from uname -r"
2847
2848}
2849
2850pp_solaris_detect_arch () {
2851	pp_solaris_arch=`/usr/bin/optisa amd64 sparcv9 i386 sparc`
2852	[ -z "$pp_solaris_arch" ] &&
2853	    pp_error "can't determine processor architecture"
2854	case "$pp_solaris_arch" in
2855	    amd64)   pp_solaris_arch_std=x86_64;;
2856	    i386)    pp_solaris_arch_std=i386;;
2857	    sparcv9) pp_solaris_arch_std=sparc64;;
2858	    sparc)   pp_solaris_arch_std=sparc;;
2859	    *)       pp_solaris_arch_std=unknown;;
2860	esac
2861}
2862
2863pp_solaris_is_request_script_necessary () {
2864    typeset has_optional_services
2865
2866    has_optional_services=no
2867    for _svc in $pp_services; do
2868    	pp_load_service_vars $_svc
2869	if test "$optional" = "yes"; then
2870	    has_optional_services=yes
2871	fi
2872    done
2873
2874    # If the package has no optional services and only one component, don't
2875    # create a request script at all.
2876    if test "$has_optional_services" = "no" &&
2877       test `echo $pp_components | wc -w` -eq 1; then
2878	return 1 # no
2879    fi
2880
2881    return 0 # yes
2882}
2883
2884pp_solaris_request () {
2885    typeset _cmp _svc
2886
2887    #-- The common part of the request script contains the ask() function
2888    #   and resets the CLASSES list to empty
2889    cat <<'.'
2890	trap 'exit 3' 15
2891	ask () {
2892	   ans=`ckyorn -d "$1" \
2893                -p "Do you want to $2"` \
2894            || exit $?
2895	   case "$ans" in y*|Y*) return 0;; *) return 1;; esac
2896	}
2897	CLASSES=
2898.
2899    #-- each of our components adds itself to the CLASSES list
2900    for _cmp in $pp_components; do
2901      case "$_cmp" in
2902            run) :;;
2903            doc) echo 'ask y "install the documentation files" &&';;
2904            dev) echo 'ask y "install the development files" &&';;
2905            dbg) echo 'ask n "install the diagnostic files" &&';;
2906      esac
2907      echo '    CLASSES="$CLASSES '$_cmp'"'
2908    done
2909
2910    #-- the request script writes the CLASSES var to its output
2911    cat <<'.'
2912	echo "CLASSES=$CLASSES" > $1
2913.
2914
2915    if test -n "$pp_services"; then
2916        echo 'SERVICES='
2917        for _svc in $pp_services; do
2918	    pp_load_service_vars $_svc
2919	    if test "$enable" = "yes"; then
2920		_default_prompt=y
2921	    else
2922		_default_prompt=n
2923	    fi
2924	    if test "$optional" = "yes"; then
2925		echo 'ask '$_default_prompt' "install '$_svc' service" &&'
2926	    fi
2927            echo '    SERVICES="$SERVICES '$_svc'"'
2928        done
2929        echo 'echo "SERVICES=$SERVICES" >> $1'
2930    fi
2931
2932}
2933
2934pp_solaris_procedure () {
2935    cat <<.
2936
2937        #-- $2 for $1 component of $name
2938        case " \$CLASSES " in *" $1 "*)
2939.
2940    cat
2941    cat <<.
2942        ;; esac
2943.
2944}
2945
2946pp_solaris_depend () {
2947    typeset _name _vers
2948    while read _name _vers; do
2949	if test -n "$_name"; then
2950	    echo "P $_name $_name"
2951	    test -n "$_vers" && echo " $_vers"
2952	fi
2953    done
2954}
2955
2956pp_solaris_conflict () {
2957    typeset _name _vers
2958    while read _name _vers; do
2959	if test -n "$_name"; then
2960	    echo "I $_name $_name"
2961	    test -n "$_vers" && echo " $_vers"
2962	fi
2963    done
2964}
2965
2966pp_solaris_space() {
2967    echo "$2:$3:$1" >> $pp_wrkdir/space.cumulative
2968}
2969
2970pp_solaris_sum_space () {
2971    if test -s $pp_wrkdir/space.cumulative; then
2972        sort -t: +2 < $pp_wrkdir/space.cumulative |
2973        awk -F: 'NR==1{n=$3}{if($3==n){b+=$1;i+=$2}else{print n" "b" "i;b=$1;i=$2;n=$3}}END{print n" "b" "i}' > $pp_wrkdir/space
2974    fi
2975}
2976
2977pp_solaris_proto () {
2978	typeset t m o g f p st
2979	typeset abi
2980
2981	while read t m o g f p st; do
2982	  # Use Solaris default mode, owner and group if all unspecified
2983	  if test x"$m$o$g" = x"---"; then
2984	    m="?"; o="?"; g="?"
2985	  fi
2986	  test x"$o" = x"-" && o="root"
2987	  case "$t" in
2988	    f) test x"$g" = x"-" && g="bin"
2989	       test x"$m" = x"-" && m=444
2990	       case "$f" in
2991		*v*) echo "v $1 $p=$pp_destdir$p $m $o $g";;
2992		*)   echo "f $1 $p=$pp_destdir$p $m $o $g";;
2993	       esac
2994	       if test -r "$pp_destdir$p"; then
2995		  #-- Use file to record ABI types seen
2996		  case "`file "$pp_destdir$p"`" in
2997		    *"ELF 32"*80386*) abi=i386;;
2998		    *"ELF 64"*AMD*) abi=x86_64;;
2999		    *"ELF 32"*SPARC*) abi=sparc;;
3000		    *"ELF 64"*SPARC*) abi=sparc64;;
3001		    *) abi=;;
3002		  esac
3003		  if test -n "$abi"; then
3004		    pp_add_to_list pp_solaris_abis_seen $abi
3005		  fi
3006	       fi
3007               ;;
3008	    d) test x"$g" = x"-" && g="sys"
3009	       test x"$m" = x"-" && m=555
3010	       echo "d $1 $p $m $o $g"
3011               ;;
3012	    s) test x"$g" = x"-" && g="bin"
3013	       test x"$m" = x"-" && m=777
3014               if test x"$m" != x"777" -a x"$m" != x"?"; then
3015                  pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
3016	       fi
3017	       echo "s $1 $p=$st $m $o $g"
3018               ;;
3019	  esac
3020	done
3021}
3022
3023pp_backend_solaris () {
3024        typeset _cmp _svc _grp
3025
3026	prototype=$pp_wrkdir/prototype
3027	: > $prototype
3028
3029	pkginfo=$pp_wrkdir/pkginfo
3030	: > $pkginfo
3031	echo "i pkginfo=$pkginfo" >> $prototype
3032
3033        case "${pp_solaris_name:-$name}" in
3034            [0-9]*)
3035                pp_error "Package name '${pp_solaris_name:-$name}'" \
3036                        "cannot start with a number"
3037                ;;
3038            ???????????????*)
3039                pp_warn "Package name '${pp_solaris_name:-$name}'" \
3040                        "too long for Solaris 2.6 or 2.7 (max 9 characters)"
3041                ;;
3042            ??????????*)
3043                pp_warn "Package name '${pp_solaris_name:-$name}'" \
3044                        "too long for 2.7 Solaris (max 9 characters)"
3045                ;;
3046        esac
3047
3048        #-- generate the package info file
3049	echo "VERSION=$version" >> $pkginfo
3050	echo "PKG=${pp_solaris_name:-$name}" >> $pkginfo
3051	echo "CLASSES=$pp_components" >> $pkginfo
3052	echo "BASEDIR=/" >> $pkginfo
3053	echo "NAME=$name $version" >> $pkginfo
3054	echo "CATEGORY=${pp_solaris_category:-application}" >> $pkginfo
3055
3056	desc="${pp_solaris_desc:-$description}"
3057	test -n "$desc" &&
3058	  echo "DESC=$desc" >> $pkginfo
3059
3060	test -n "$pp_solaris_rstates" &&
3061	  echo "RSTATES=$pp_solaris_rstates" >> $pkginfo
3062	test -n "$pp_solaris_istates" &&
3063	  echo "ISTATES=$pp_solaris_istates" >> $pkginfo
3064	test -n "$pp_solaris_maxinst" &&
3065	  echo "MAXINST=$pp_solaris_maxinst" >> $pkginfo
3066	test -n "${pp_solaris_vendor:-$vendor}" &&
3067	  echo "VENDOR=${pp_solaris_vendor:-$vendor}" >> $pkginfo
3068	test -n "$pp_solaris_pstamp" &&
3069	  echo "PSTAMP=$pp_solaris_pstamp" >> $pkginfo
3070
3071	if test -n "${pp_solaris_copyright:-$copyright}"; then
3072	    echo "${pp_solaris_copyright:-$copyright}" > $pp_wrkdir/copyright
3073	    echo "i copyright=$pp_wrkdir/copyright" >> $prototype
3074	fi
3075
3076        #-- scripts to run before and after install
3077        : > $pp_wrkdir/postinstall
3078        : > $pp_wrkdir/preremove
3079        : > $pp_wrkdir/postremove
3080	for _cmp in $pp_components; do
3081        #-- add the preinstall scripts in definition order
3082        if test -s $pp_wrkdir/%pre.$_cmp; then
3083            pp_solaris_procedure $_cmp preinst < $pp_wrkdir/%pre.$_cmp \
3084                >> $pp_wrkdir/preinstall
3085        fi
3086        #-- add the postinstall scripts in definition order
3087        if test -s $pp_wrkdir/%post.$_cmp; then
3088            pp_solaris_procedure $_cmp postinst < $pp_wrkdir/%post.$_cmp \
3089                >> $pp_wrkdir/postinstall
3090        fi
3091        #-- add the preremove rules in reverse definition order
3092        if test -s $pp_wrkdir/%preun.$_cmp; then
3093            pp_solaris_procedure $_cmp preremove < $pp_wrkdir/%preun.$_cmp |
3094                    pp_prepend $pp_wrkdir/preremove
3095        fi
3096        #-- add the postremove scripts in definition order
3097        if test -s $pp_wrkdir/%postun.$_cmp; then
3098            pp_solaris_procedure $_cmp postremove < $pp_wrkdir/%postun.$_cmp \
3099                >> $pp_wrkdir/postremove
3100        fi
3101        #-- Add the check script in definition order
3102        if test -s $pp_wrkdir/%check.$_cmp; then
3103            pp_solaris_procedure $_cmp checkinstall \
3104                        < $pp_wrkdir/%check.$_cmp \
3105			>> $pp_wrkdir/checkinstall
3106        fi
3107        #-- All dependencies and conflicts are merged together for Solaris pkgs
3108        test -s $pp_wrkdir/%depend.$_cmp &&
3109              pp_solaris_depend < $pp_wrkdir/%depend.$_cmp >> $pp_wrkdir/depend
3110        test -s $pp_wrkdir/%conflict.$_cmp &&
3111              pp_solaris_conflict < $pp_wrkdir/%conflict.$_cmp >> $pp_wrkdir/depend
3112	done
3113
3114
3115	if pp_solaris_is_request_script_necessary; then
3116	    pp_solaris_request > $pp_wrkdir/request
3117	fi
3118
3119        test -n "$pp_services" &&
3120            for _svc in $pp_services; do
3121                pp_load_service_vars $_svc
3122                pp_solaris_smf $_svc
3123                pp_solaris_make_service $_svc
3124                pp_solaris_install_service $_svc | pp_prepend $pp_wrkdir/postinstall
3125                pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/preremove
3126                pp_solaris_remove_service $_svc | pp_prepend $pp_wrkdir/postremove
3127                unset pp_svc_xml_file
3128            done
3129
3130        test -n "$pp_service_groups" &&
3131	    for _grp in $pp_service_groups; do
3132		pp_solaris_make_service_group \
3133		    $_grp "`pp_service_get_svc_group $_grp`"
3134	    done
3135
3136        #-- if installf was used; we need to indicate a termination
3137        grep installf $pp_wrkdir/postinstall >/dev/null &&
3138            echo 'installf -f $PKGINST' >> $pp_wrkdir/postinstall
3139
3140        pp_solaris_sum_space
3141
3142        # NB: pkginfo and copyright are added earlier
3143        for f in compver depend space checkinstall \
3144                 preinstall request postinstall \
3145                 preremove postremove; do
3146            if test -s $pp_wrkdir/$f; then
3147		case $f in
3148		    *install|*remove|request)
3149			# turn scripts into a proper shell scripts
3150			mv $pp_wrkdir/$f $pp_wrkdir/$f.tmp
3151			{ echo "#!/bin/sh";
3152			  echo "# $f script for ${pp_solaris_name:-$name}-$version"
3153			  cat $pp_wrkdir/$f.tmp
3154			  echo "exit 0"; } > $pp_wrkdir/$f
3155			chmod +x $pp_wrkdir/$f
3156			rm -f $pp_wrkdir/$f.tmp
3157			;;
3158		esac
3159                if $pp_opt_debug; then
3160                    pp_debug "contents of $f:"
3161                    cat $pp_wrkdir/$f >&2
3162                fi
3163                echo "i $f=$pp_wrkdir/$f" >> $prototype
3164            fi
3165        done
3166
3167        #-- create the prototype file which lists the files to install
3168        # do this as late as possible because files could be added
3169	pp_solaris_abis_seen=
3170	for _cmp in $pp_components; do
3171	  pp_solaris_proto $_cmp < $pp_wrkdir/%files.$_cmp
3172	done >> $prototype
3173
3174	if test x"$pp_solaris_package_arch" = x"auto"; then
3175	    if pp_contains "$pp_solaris_abis_seen" sparc64; then
3176		pp_solaris_package_arch_std="sparc64"
3177		echo "ARCH=sparcv9" >> $pkginfo
3178	    elif pp_contains "$pp_solaris_abis_seen" sparc; then
3179		pp_solaris_package_arch_std="sparc"
3180		echo "ARCH=sparc" >> $pkginfo
3181	    elif pp_contains "$pp_solaris_abis_seen" x86_64; then
3182		pp_solaris_package_arch_std="x86_64"
3183		echo "ARCH=amd64" >> $pkginfo
3184	    elif pp_contains "$pp_solaris_abis_seen" i386; then
3185		pp_solaris_package_arch_std="i386"
3186		echo "ARCH=i386" >> $pkginfo
3187	    else
3188		pp_warn "No ELF files found: not supplying an ARCH type"
3189		pp_solaris_package_arch_std="noarch"
3190	    fi
3191	else
3192	    pp_solaris_package_arch_std="$pp_solaris_package_arch"
3193	    echo "ARCH=$pp_solaris_package_arch" >> $pkginfo
3194	fi
3195
3196	mkdir $pp_wrkdir/pkg
3197
3198	. $pp_wrkdir/%fixup
3199
3200if $pp_opt_debug; then
3201  echo "$pkginfo::"; cat $pkginfo
3202  echo "$prototype::"; cat $prototype
3203fi >&2
3204
3205	pkgmk -d $pp_wrkdir/pkg -f $prototype \
3206		|| { error "pkgmk failed"; return; }
3207        pkgtrans -s $pp_wrkdir/pkg \
3208		$pp_wrkdir/`pp_backend_solaris_names` \
3209                ${pp_solaris_name:-$name} \
3210		|| { error "pkgtrans failed"; return; }
3211}
3212
3213pp_backend_solaris_cleanup () {
3214	:
3215}
3216
3217pp_backend_solaris_names () {
3218	echo ${pp_solaris_name:-$name}-$version-${pp_solaris_package_arch_std:-$pp_solaris_arch}.pkg
3219}
3220
3221pp_backend_solaris_install_script () {
3222        typeset pkgname platform
3223
3224	platform="${pp_solaris_os:-solaris}-${pp_solaris_package_arch_std:-$pp_solaris_arch}"
3225
3226        echo "#! /sbin/sh"
3227        pp_install_script_common
3228        pkgname=`pp_backend_solaris_names`
3229
3230        cat <<.
3231            tmpnocheck=/tmp/nocheck\$\$
3232            tmpresponse=/tmp/response\$\$
3233            trap 'rm -f \$tmpnocheck \$tmpresponse' 0
3234
3235            make_tmpfiles () {
3236                cat <<-.. > \$tmpresponse
3237                        CLASSES=\$*
3238                        SERVICES=$pp_services
3239..
3240                cat <<-.. > \$tmpnocheck
3241			mail=
3242			instance=overwrite
3243			partial=nocheck
3244			runlevel=nocheck
3245			idepend=nocheck
3246			rdepend=nocheck
3247			space=nocheck
3248			setuid=nocheck
3249			conflict=nocheck
3250			action=nocheck
3251			basedir=default
3252..
3253            }
3254
3255            test \$# -eq 0 && usage
3256            op="\$1"; shift
3257
3258            case "\$op" in
3259                list-components)
3260                    test \$# -eq 0 || usage \$op
3261                    echo "$pp_components"
3262                    ;;
3263                list-services)
3264                    test \$# -eq 0 || usage \$op
3265                    echo "$pp_services"
3266                    ;;
3267                list-files)
3268                    test \$# -ge 1 || usage \$op
3269                    echo \${PP_PKGDESTDIR:-.}/$pkgname
3270                    ;;
3271                install)
3272                    test \$# -ge 1 || usage \$op
3273                    make_tmpfiles "\$@"
3274                    verbose /usr/sbin/pkgadd -n -d \${PP_PKGDESTDIR:-.}/$pkgname \
3275                        -r \$tmpresponse \
3276                        -a \$tmpnocheck \
3277                        ${pp_solaris_name:-$name}
3278                    ;;
3279                uninstall)
3280                    test \$# -ge 1 || usage \$op
3281                    make_tmpfiles "\$@"
3282                    verbose /usr/sbin/pkgrm -n \
3283                        -a \$tmpnocheck \
3284                        ${pp_solaris_name:-$name}
3285                    ;;
3286                start|stop)
3287                    test \$# -ge 1 || usage \$op
3288                    ec=0
3289                    for svc
3290                    do
3291                        verbose /etc/init.d/\$svc \$op || ec=1
3292                    done
3293                    exit \$ec
3294                    ;;
3295                print-platform)
3296		    echo "$platform"
3297		    ;;
3298                *)
3299                    usage
3300                    ;;
3301            esac
3302.
3303}
3304
3305pp_solaris_dynlib_depend () {
3306	xargs ldd 2>/dev/null |
3307	sed -e '/^[^ 	]*:$/d' -e 's,.*=>[	 ]*,,' -e 's,^[ 	]*,,' |
3308	sort -u |
3309	grep -v '^/usr/platform/' | (
3310	  set -- ""; shift
3311	  while read p; do
3312	    set -- "$@" -p "$p"
3313	    if [ $# -gt 32 ]; then
3314		echo "$# is $#" >&2
3315		pkgchk -l "$@"
3316		set -- ""; shift
3317	    fi
3318	  done
3319	  [ $# -gt 0 ] && pkgchk -l "$@"
3320	)|
3321	awk '/^Current status:/{p=0} p==1 {print $1} /^Referenced by/ {p=1}' |
3322	sort -u |
3323	xargs -l32 pkginfo -x |
3324	awk 'NR % 2 == 1 { name=$1; } NR%2 == 0 { print name, $2 }'
3325}
3326
3327pp_solaris_add_dynlib_depends () {
3328    typeset tmp
3329    tmp=$pp_wrkdir/tmp.dynlib
3330
3331    for _cmp in $pp_components; do
3332	awk '{print destdir $6}' destdir="$pp_destdir" \
3333		< $pp_wrkdir/%files.$_cmp |
3334	pp_solaris_dynlib_depend > $tmp
3335	if test -s $tmp; then
3336	    cat $tmp >> $pp_wrkdir/%depend.$_cmp
3337	fi
3338	rm -f $tmp
3339    done
3340}
3341
3342pp_backend_solaris_probe () {
3343    echo "${pp_solaris_os}-${pp_solaris_arch_std}"
3344}
3345
3346pp_backend_solaris_vas_platforms () {
3347    case `pp_backend_solaris_probe` in
3348	sol10-sparc* | sol9-sparc* | sol8-sparc*)
3349			echo solaris8-sparc solaris7-sparc solaris26-sparc;;
3350	sol7-sparc*)	echo                solaris7-sparc solaris26-sparc;;
3351	sol26-sparc*)	echo                               solaris26-sparc;;
3352	sol8-*86)	echo solaris8-x86;;
3353	sol10-*86 | sol10-x86_64)
3354			echo solaris10-x64 solaris8-x86;;
3355	*)		pp_die "unknown system `pp_backend_solaris_probe`";;
3356    esac
3357}
3358pp_backend_solaris_function() {
3359    case "$1" in
3360        pp_mkgroup) cat<<'.';;
3361	    /usr/sbin/groupmod "$1" 2>/dev/null && return 0
3362            /usr/sbin/groupadd "$1"
3363.
3364        pp_mkuser:depends) echo pp_mkgroup;;
3365        pp_mkuser) cat<<'.';;
3366	    id "$1" >/dev/null 2>/dev/null && return 0
3367	    pp_mkgroup "${2:-$1}" || return 1
3368	    /usr/sbin/useradd \
3369		-g "${2:-$1}" \
3370		-d "${3:-/nonexistent}" \
3371		-s "${4:-/bin/false}" \
3372		"$1"
3373.
3374    *) false;;
3375    esac
3376}
3377
3378pp_backend_solaris_init_svc_vars () {
3379    _smf_category=${pp_solaris_smf_category:-application}
3380    _smf_method_envvar_name=${smf_method_envvar_name:-"PP_SMF_SERVICE"}
3381    pp_solaris_service_shell=/sbin/sh
3382}
3383
3384pp_solaris_init_svc () {
3385    smf_version=1
3386    smf_type=service
3387    solaris_user=
3388    solaris_stop_signal=
3389    solaris_sysv_init_start=S70     # invocation order for start scripts
3390    solaris_sysv_init_kill=K30      # invocation order for kill scripts
3391    solaris_sysv_init_start_states="2" # states to install start link
3392    solaris_sysv_init_kill_states="S 0 1"  # states to install kill link
3393
3394    #
3395    # To have the service be installed to start automatically,
3396    #   %service foo
3397    #   solaris_sysv_init_start_states="S 0 1 2"
3398    #
3399}
3400
3401pp_solaris_smf () {
3402    typeset f _pp_solaris_service_script svc _pp_solaris_manpage
3403
3404    pp_solaris_name=${pp_solaris_name:-$name}
3405    pp_solaris_manpath=${pp_solaris_manpath:-"/usr/share/man"}
3406    pp_solaris_mansect=${pp_solaris_mansect:-1}
3407    smf_start_timeout=${smf_start_timeout:-60}
3408    smf_stop_timeout=${smf_stop_timeout:-60}
3409    smf_restart_timeout=${smf_restart_timeout:-60}
3410
3411    svc=${pp_solaris_smf_service_name:-$1}
3412    _pp_solaris_service_script=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
3413    _pp_solaris_manpage=${pp_solaris_manpage:-$svc}
3414
3415    if [ -z $pp_svc_xml_file ]; then
3416        pp_svc_xml_file="/var/svc/manifest/$_smf_category/$svc.xml"
3417        echo "## Generating the smf service manifest file for $pp_svc_xml_file"
3418    else
3419        echo "## SMF service manifest file already defined at $pp_svc_xml_file"
3420        if [ -z $pp_solaris_smf_service_name ] || [ -z $pp_solaris_smf_category ] || [ -z $pp_solaris_service_script ] || [ -z $smf_method_envvar_name ]; then
3421          pp_error "All required variables are not set.\n"\
3422                   "When using a custom manifest file all of the following variables must be set:\n"\
3423                   "pp_solaris_smf_service_name, pp_solaris_smf_category, pp_solaris_service_script and smf_method_envvar_name.\n\n"\
3424                   "Example:\n"\
3425                   " \$pp_solaris_smf_category=application\n"\
3426                   " \$pp_solaris_smf_service_name=pp\n\n"\
3427                   "  <service name='application/pp' type='service' version='1'>\n\n"\
3428                   "Example:\n"\
3429                   " \$pp_solaris_service_script=/etc/init.d/pp\n\n"\
3430                   "  <exec_method type='method' name='start' exec='/etc/init.d/pp' />\n\n"\
3431                   "Example:\n"\
3432                   " \$smf_method_envvar_name=PP_SMF_SERVICE\n\n"\
3433                   "  <method_environment>\n"\
3434                   "    <envvar name='PP_SMF_SERVICE' value='1'/>\n"\
3435                   "  </method_environment>\n"
3436
3437          return 1
3438        fi
3439        return 0
3440    fi
3441
3442    f=$pp_svc_xml_file
3443    pp_add_file_if_missing $f ||
3444        return 0
3445    pp_solaris_add_parent_dirs "$f"
3446
3447    _pp_solaris_smf_dependencies="
3448          <dependency name='pp_local_filesystems'
3449                grouping='require_all'
3450                restart_on='none'
3451                type='service'>
3452                <service_fmri value='svc:/system/filesystem/local'/>
3453          </dependency>
3454
3455          <dependency name='pp_single-user'
3456                grouping='require_all'
3457                restart_on='none'
3458                type='service'>
3459                <service_fmri value='svc:/milestone/single-user' />
3460          </dependency>
3461"
3462    _pp_solaris_smf_dependencies=${pp_solaris_smf_dependencies:-$_pp_solaris_smf_dependencies}
3463
3464    cat <<-. >$pp_destdir$f
3465<?xml version="1.0"?>
3466<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
3467<!--
3468	$copyright
3469        Generated by PolyPackage $pp_version
3470-->
3471
3472    <service_bundle type='manifest' name='${pp_solaris_name}:${svc}' >
3473          <service name='$_smf_category/$svc'
3474                type='$smf_type'
3475                version='$smf_version'>
3476
3477          <create_default_instance enabled='false'/>
3478
3479          <single_instance />
3480
3481          $_pp_solaris_smf_dependencies
3482
3483          $pp_solaris_smf_additional_dependencies
3484
3485          <method_context>
3486                <method_credential user='${solaris_user:-$user}' />
3487                <method_environment>
3488                    <envvar name='$_smf_method_envvar_name' value='1'/>
3489                </method_environment>
3490          </method_context>
3491
3492          <exec_method type='method' name='start'
3493                exec='$_pp_solaris_service_script start'
3494                timeout_seconds='$smf_start_timeout' />
3495
3496          <exec_method type='method' name='stop'
3497                exec='$_pp_solaris_service_script stop'
3498                timeout_seconds='$smf_stop_timeout' />
3499
3500          <exec_method type='method' name='restart'
3501                exec='$_pp_solaris_service_script restart'
3502                timeout_seconds='$smf_restart_timeout' />
3503
3504          <template>
3505              <common_name>
3506                  <loctext xml:lang='C'>$description</loctext>
3507              </common_name>
3508              <documentation>
3509                  <manpage title='$pp_solaris_manpage' section='$pp_solaris_mansect' manpath='$pp_solaris_manpath'/>
3510              </documentation>
3511          </template>
3512        </service>
3513    </service_bundle>
3514.
3515}
3516
3517pp_solaris_make_service_group () {
3518    typeset group out file svcs svc
3519
3520    group="$1"
3521    svcs="$2"
3522    file="/etc/init.d/$group"
3523    out="$pp_destdir$file"
3524
3525    #-- return if the script is supplied already
3526    pp_add_file_if_missing "$file" run 755 || return 0
3527    pp_solaris_add_parent_dirs "$file"
3528
3529    echo "#! /sbin/sh" > $out
3530    echo "# polypkg service group script for these services:" >> $out
3531    echo "svcs=\"$svcs\"" >> $out
3532
3533    cat <<'.' >>$out
3534
3535	#-- starts services in order.. stops them all if any break
3536	pp_start () {
3537	    undo=
3538	    for svc in $svcs; do
3539		if /etc/init.d/$svc start; then
3540		    undo="$svc $undo"
3541		else
3542		    if test -n "$undo"; then
3543		        for svc in $undo; do
3544			   /etc/init.d/$svc stop
3545			done
3546			return 1
3547		    fi
3548		fi
3549	    done
3550	    return 0
3551	}
3552
3553	#-- stops services in reverse
3554	pp_stop () {
3555	    reverse=
3556	    for svc in $svcs; do
3557		reverse="$svc $reverse"
3558	    done
3559	    rc=0
3560	    for svc in $reverse; do
3561		/etc/init.d/$svc stop || rc=$?
3562	    done
3563	    return $rc
3564	}
3565
3566	#-- returns true only if all services return true status
3567	pp_status () {
3568	    rc=0
3569	    for svc in $svcs; do
3570		/etc/init.d/$svc status || rc=$?
3571	    done
3572	    return $rc
3573	}
3574
3575        case "$1" in
3576            start)   pp_start;;
3577            stop)    pp_stop;;
3578            status)  pp_status;;
3579            restart) pp_stop && pp_start;;
3580            *)       echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
3581        esac
3582.
3583}
3584
3585pp_solaris_make_service () {
3586    typeset file out _cmd svc
3587
3588    svc="${pp_solaris_smf_service_name:-$1}"
3589    file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
3590    out="$pp_destdir$file"
3591
3592    #-- return if we don't need to create the init script
3593    pp_add_file_if_missing "$file" run 755 ||
3594        return 0
3595    pp_solaris_add_parent_dirs "$file"
3596
3597    echo "#! /sbin/sh" >$out
3598    echo "#-- This service init file generated by polypkg" >>$out
3599
3600    #-- Start SMF integration.
3601    if [ -n "$pp_svc_xml_file" ] ; then
3602        cat <<_EOF >>$out
3603if [ -x /usr/sbin/svcadm ] && [ "x\$1" != "xstatus" ] && [ "t\$$_smf_method_envvar_name" = "t" ] ; then
3604    case "\$1" in
3605        start)
3606            echo "starting $svc"
3607            /usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
3608            /usr/sbin/svcadm enable -s $_smf_category/$svc
3609            RESULT=\$?
3610            if [ "\$RESULT" -ne 0 ] ; then
3611                echo "Error \$RESULT starting $svc" >&2
3612            fi
3613            ;;
3614        stop)
3615            echo "stopping $svc"
3616            /usr/sbin/svcadm disable -ts $_smf_category/$svc
3617	    RESULT=0
3618            ;;
3619        restart)
3620            echo "restarting $svc"
3621            /usr/sbin/svcadm disable -ts $_smf_category/$svc
3622            /usr/sbin/svcadm clear svc:/$_smf_category/$svc:default >/dev/null 2>&1
3623            /usr/sbin/svcadm enable -s $_smf_category/$svc
3624            RESULT=\$?
3625            if [ "\$RESULT" -ne 0 ] ; then
3626                echo "Error \$RESULT starting $svc" >&2
3627            fi
3628            ;;
3629        *)
3630            echo "Usage: $file {start|stop|restart|status}" >&2
3631            RESULT=1
3632    esac
3633    exit $RESULT
3634fi
3635_EOF
3636    fi
3637
3638    #-- construct a start command that builds a pid file as needed
3639    #   and forks the daemon
3640    _cmd="$cmd";
3641    if test -z "$pidfile"; then
3642	# The service does not define a pidfile, so we have to make
3643	# our own up. On Solaris systems where there is no /var/run
3644	# we must use /tmp to guarantee the pid files are removed after
3645	# a system crash.
3646	cat <<. >>$out
3647	    pp_piddir="/var/run"
3648	    test -d "\$pp_piddir/." || pp_piddir="/tmp"
3649	    pidfile="\$pp_piddir/$svc.pid"
3650.
3651        _cmd="$cmd & echo \$! > \$pidfile"
3652    else
3653	# The service is able to write its own PID file
3654	cat <<. >>$out
3655	    pidfile="$pidfile"
3656.
3657    fi
3658
3659    if test "${user:-root}" != "root"; then
3660        _cmd="su $user -c exec $_cmd";
3661    fi
3662
3663    cat <<. >>$out
3664	stop_signal="${stop_signal:-TERM}"
3665	svc="${svc}"
3666
3667        # generated command to run $svc as a daemon process
3668        pp_exec () { $_cmd; }
3669.
3670
3671    #-- write the invariant section of the init script
3672    cat <<'.' >>$out
3673
3674        # returns true if $svc is running
3675        pp_running () {
3676            test -s "$pidfile" || return 1
3677            read pid junk < "$pidfile" 2>/dev/null
3678            test ${pid:-0} -gt 1 &&
3679            kill -0 "$pid" 2>/dev/null
3680        }
3681
3682        # prints a message describing $svc's running state
3683        pp_status () {
3684            if pp_running; then
3685                echo "service $svc is running (pid $pid)"
3686                return 0
3687            elif test -f "$pidfile"; then
3688                echo "service $svc is not running, but pid file exists"
3689                return 2
3690            else
3691                echo "service $svc is not running"
3692                return 1
3693            fi
3694        }
3695
3696        # starts $svc
3697        pp_start () {
3698            if pp_running; then
3699                echo "service $svc already running" >&2
3700                return 0
3701            fi
3702            echo "starting $svc... \c"
3703            if pp_exec; then
3704                echo "done."
3705            else
3706                echo "ERROR."
3707                exit 1
3708            fi
3709        }
3710
3711        # stops $svc
3712        pp_stop () {
3713            if pp_running; then
3714                echo "stopping $svc... \c"
3715                if kill -$stop_signal $pid; then
3716                    rm -f "$pidfile"
3717                    echo "done."
3718                else
3719                    echo "ERROR."
3720                    return 1
3721                fi
3722            else
3723                echo "service $svc already stopped" >&2
3724                return 0
3725            fi
3726        }
3727
3728        umask 022
3729        case "$1" in
3730            start)   pp_start;;
3731            stop)    pp_stop;;
3732            status)  pp_status;;
3733            restart) pp_stop && pp_start;;
3734            *)       echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
3735        esac
3736.
3737}
3738
3739pp_solaris_remove_service () {
3740    typeset file svc
3741
3742    svc="${pp_solaris_smf_service_name:-$1}"
3743    file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
3744
3745    echo '
3746'$file' stop >/dev/null 2>/dev/null
3747if [ "x${PKG_INSTALL_ROOT}" = 'x' ]; then
3748    if [ -x /usr/sbin/svcadm ] ; then
3749        # Likely un-needed, but just in case.
3750        /usr/sbin/svcadm disable -s '$svc' 2>/dev/null
3751        /usr/sbin/svccfg delete '$svc' 2>/dev/null
3752    fi
3753fi
3754    '
3755}
3756
3757pp_solaris_install_service () {
3758    typeset s k l file svc
3759
3760    svc="${pp_solaris_smf_service_name:-$1}"
3761    file=${pp_solaris_service_script:-"/etc/init.d/${pp_solaris_service_script_name:-$svc}"}
3762
3763    s="${solaris_sysv_init_start}$svc"
3764    k="${solaris_sysv_init_kill}$svc"
3765
3766    echo '
3767if [ "x${PKG_INSTALL_ROOT}" != "x" ]; then
3768  if [ -x ${PKG_INSTALL_ROOT}/usr/sbin/svcadm ]; then
3769    echo "/usr/sbin/svccfg import '$pp_svc_xml_file' 2>/dev/null" >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade
3770  else'
3771    test -n "${solaris_sysv_init_start_states}" &&
3772        for state in ${solaris_sysv_init_start_states}; do
3773            l="/etc/rc$state.d/$s"
3774            echo "echo '$l'"
3775            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
3776            pp_solaris_space /etc/rc$state.d 0 1
3777        done
3778    test -n "${solaris_sysv_init_kill_states}" &&
3779        for state in ${solaris_sysv_init_kill_states}; do
3780            l="/etc/rc$state.d/$k"
3781            echo "echo '$l'"
3782            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
3783            pp_solaris_space /etc/rc$state.d 0 1
3784        done
3785    echo '
3786  fi
3787else
3788    if [ -x /usr/sbin/svcadm ]; then
3789        echo "Registering '$svc' with SMF"
3790        /usr/sbin/svcadm disable -s '$svc' 2>/dev/null
3791        /usr/sbin/svccfg delete '$svc' 2>/dev/null
3792        /usr/sbin/svccfg import '$pp_svc_xml_file'
3793    else'
3794    test -n "${solaris_sysv_init_start_states}" &&
3795        for state in ${solaris_sysv_init_start_states}; do
3796            l="/etc/rc$state.d/$s"
3797            echo "echo '$l'"
3798            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
3799            pp_solaris_space /etc/rc$state.d 0 1
3800        done
3801    test -n "${solaris_sysv_init_kill_states}" &&
3802        for state in ${solaris_sysv_init_kill_states}; do
3803            l="/etc/rc$state.d/$k"
3804            echo "echo '$l'"
3805            echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=$file s"
3806            pp_solaris_space /etc/rc$state.d 0 1
3807        done
3808    echo '
3809    fi
3810fi'
3811}
3812
3813pp_solaris_add_parent_dirs () {
3814    typeset dir
3815
3816    dir=${1%/*}
3817    while test -n "$dir"; do
3818	if awk "\$6 == \"$dir/\" {exit 1}" < $pp_wrkdir/%files.run; then
3819	    echo "d - - - - $dir/" >> $pp_wrkdir/%files.run
3820	fi
3821	dir=${dir%/*}
3822    done
3823}
3824
3825pp_platforms="$pp_platforms deb"
3826
3827pp_backend_deb_detect () {
3828    test -f /etc/debian_version
3829}
3830
3831pp_deb_cmp_full_name () {
3832    local prefix
3833    prefix="${pp_deb_name:-$name}"
3834    case "$1" in
3835        run) echo "${prefix}" ;;
3836        dbg) echo "${prefix}-${pp_deb_dbg_pkgname}";;
3837        dev) echo "${prefix}-${pp_deb_dev_pkgname}";;
3838        doc) echo "${prefix}-${pp_deb_doc_pkgname}";;
3839        *)   pp_error "unknown component '$1'";
3840    esac
3841}
3842
3843pp_backend_deb_init () {
3844    pp_deb_dpkg_version="2.0"
3845    pp_deb_name=
3846    pp_deb_version=
3847    pp_deb_release=
3848    pp_deb_arch=
3849    pp_deb_arch_std=
3850    pp_deb_maintainer="Quest Software, Inc <support@quest.com>"
3851    pp_deb_copyright=
3852    pp_deb_distro=
3853    pp_deb_control_description=
3854    pp_deb_summary=
3855    pp_deb_description=
3856    pp_deb_dbg_pkgname="dbg"
3857    pp_deb_dev_pkgname="dev"
3858    pp_deb_doc_pkgname="doc"
3859    pp_deb_section=contrib # Free software that depends on non-free software
3860
3861    # Detect the host architecture
3862    pp_deb_detect_arch
3863
3864    # Make sure any programs we require are installed
3865    pp_deb_check_required_programs
3866}
3867
3868pp_deb_check_required_programs () {
3869    local p needed notfound ok
3870    needed= notfound=
3871    for prog in dpkg dpkg-deb install md5sum fakeroot
3872    do
3873        if which $prog 2>/dev/null >/dev/null; then
3874	    pp_debug "$prog: found"
3875	else
3876	    pp_debug "$prog: not found"
3877	    case "$prog" in
3878		dpkg|dpkg-deb)	p=dpkg;;
3879		install|md5sum) p=coreutils;;
3880		fakeroot)	p=fakeroot;;
3881		*)		pp_die "unexpected dpkg tool $prog";;
3882	    esac
3883	    notfound="$notfound $prog"
3884	    pp_contains "$needed" "$p" || needed="$needed $p"
3885	fi
3886    done
3887    if [ -n "$notfound" ]; then
3888	pp_error "cannot find these programs: $notfound"
3889	pp_error "please install these packages: $needed"
3890    fi
3891}
3892
3893pp_deb_munge_description () {
3894    # Insert a leading space on each line, replace blank lines with a
3895    #space followed by a full-stop.
3896    pp_deb_control_description="`echo ${pp_deb_description:-$description} | \
3897        sed 's,^\(.*\)$, \1, ' | sed 's,^[ \t]*$, .,g' | fmt -w 80`"
3898}
3899
3900pp_deb_detect_arch () {
3901   pp_deb_arch=`dpkg --print-architecture`
3902   pp_deb_arch_std=`uname -m`
3903}
3904
3905pp_deb_sanitize_version() {
3906    echo "$@" | tr -d -c '[:alnum:].+-:~'
3907}
3908
3909pp_deb_version_final() {
3910    if test -n "$pp_deb_version"; then
3911        # Don't sanitize; assume the user is sane (hah!)
3912        echo "$pp_deb_version"
3913    else
3914        pp_deb_sanitize_version "$version"
3915    fi
3916}
3917
3918pp_deb_conflict () {
3919    local _name _vers _conflicts
3920
3921    _conflicts="Conflicts:"
3922    while read _name _vers; do
3923	case "$_name" in ""| "#"*) continue ;; esac
3924	_conflicts="$_conflicts $_name"
3925	test -n "$_vers" && _conflicts="$_conflicts $_name (>= $vers)"
3926	_conflicts="${_conflicts},"
3927    done
3928    echo "${_conflicts%,}"
3929}
3930
3931pp_deb_make_control() {
3932    local cmp="$1"
3933    local installed_size
3934
3935    # compute the installed size
3936    installed_size=`pp_deb_files_size < $pp_wrkdir/%files.$cmp`
3937
3938    package_name=`pp_deb_cmp_full_name "$cmp"`
3939    cat <<-.
3940	Package: ${package_name}
3941	Version: `pp_deb_version_final`-${pp_deb_release:-1}
3942	Section: ${pp_deb_section:-contrib}
3943	Priority: optional
3944	Architecture: ${pp_deb_arch}
3945	Maintainer: ${pp_deb_maintainer:-$maintainer}
3946	Description: ${pp_deb_summary:-$summary}
3947	${pp_deb_control_description}
3948	Installed-Size: ${installed_size}
3949.
3950    if test -s $pp_wrkdir/%depend."$cmp"; then
3951	sed -ne '/^[ 	]*$/!s/^[ 	]*/Depends: /p' \
3952	    < $pp_wrkdir/%depend."$cmp"
3953    fi
3954    if test -s $pp_wrkdir/%conflict."$cmp"; then
3955	pp_deb_conflict < $pp_wrkdir/%conflict."$cmp"
3956    fi
3957}
3958
3959pp_deb_make_md5sums() {
3960    local cmp="$1"; shift
3961    local pkg_dir
3962
3963    pkg_dir=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
3964    (cd $pkg_dir && md5sum "$@") > $pkg_dir/DEBIAN/md5sums ||
3965	pp_error "cannot make md5sums"
3966}
3967
3968pp_deb_make_package_maintainer_script() {
3969    local output="$1"
3970    local source="$2"
3971    local desc="$3"
3972
3973    # See if we need to create this script at all
3974    if [ -s "$source" ]
3975    then
3976
3977        # Create header
3978        cat <<-. >$output || pp_error "Cannot create $output"
3979	#!/bin/sh
3980	# $desc
3981	# Generated by PolyPackage $pp_version
3982
3983.
3984
3985        cat $source >> "$output" || pp_error "Cannot append to $output"
3986
3987        # Set perms
3988        chmod 755 "$output" || pp_error "Cannot chmod $output"
3989    fi
3990}
3991
3992pp_deb_handle_services() {
3993    local svc
3994
3995    #-- add service start/stop code
3996    if test -n "$pp_services"; then
3997        #-- record the uninstall commands in reverse order
3998        for svc in $pp_services; do
3999            pp_load_service_vars $svc
4000
4001            # Create init script (unless one exists)
4002            pp_deb_service_make_init_script $svc
4003
4004            #-- append %post code to install the svc
4005	    test x"yes" = x"$enable" &&
4006            cat<<-. >> $pp_wrkdir/%post.run
4007		case "\$1" in
4008		    configure)
4009		        # Install the service links
4010		        update-rc.d $svc defaults
4011		        ;;
4012		esac
4013.
4014
4015            #-- prepend %preun code to stop svc
4016            cat<<-. | pp_prepend $pp_wrkdir/%preun.run
4017		case "\$1" in
4018		    remove|deconfigure|upgrade)
4019		        # Stop the $svc service
4020		        invoke-rc.d $svc stop
4021		        ;;
4022		esac
4023.
4024
4025            #-- prepend %postun code to remove service
4026            cat<<-. | pp_prepend $pp_wrkdir/%postun.run
4027		case "\$1" in
4028		    purge)
4029		        # Remove the service links
4030		        update-rc.d $svc remove
4031		        ;;
4032		esac
4033.
4034        done
4035        #pp_deb_service_remove_common | pp_prepend $pp_wrkdir/%preun.run
4036    fi
4037
4038}
4039pp_deb_fakeroot () {
4040    if test -s $pp_wrkdir/fakeroot.save; then
4041	fakeroot -i $pp_wrkdir/fakeroot.save -s $pp_wrkdir/fakeroot.save "$@"
4042    else
4043	fakeroot -s $pp_wrkdir/fakeroot.save "$@"
4044    fi
4045}
4046
4047pp_deb_files_size () {
4048    local t m o g f p st
4049    while read t m o g f p st; do
4050        case $t in
4051            f|s) du -k "${pp_destdir}$p";;
4052            d)   echo 4;;
4053        esac
4054    done | awk '{n+=$1} END {print n}'
4055}
4056
4057pp_deb_make_DEBIAN() {
4058    local cmp="${1:-run}"
4059    local data cmp_full_name
4060    local old_umask
4061
4062    old_umask=`umask`
4063    umask 0022
4064    cmp_full_name=`pp_deb_cmp_full_name $cmp`
4065    data=$pp_wrkdir/$cmp_full_name
4066
4067    # Create DEBIAN dir $data/DEBIAN
4068    mkdir -p $data/DEBIAN
4069
4070    # Create control file
4071    pp_deb_make_control $cmp > $data/DEBIAN/control
4072
4073    # Copy in conffiles
4074    if test -f $pp_wrkdir/%conffiles.$cmp; then
4075	cp $pp_wrkdir/%conffiles.$cmp $data/DEBIAN/conffiles
4076    fi
4077
4078    # Create preinst
4079    pp_deb_make_package_maintainer_script "$data/DEBIAN/preinst" \
4080        "$pp_wrkdir/%pre.$cmp" "Pre-install script for $cmp_full_name"\
4081        || exit $?
4082
4083    # Create postinst
4084    pp_deb_make_package_maintainer_script "$data/DEBIAN/postinst" \
4085        "$pp_wrkdir/%post.$cmp" "Post-install script for $cmp_full_name"\
4086        || exit $?
4087
4088    # Create prerm
4089    pp_deb_make_package_maintainer_script "$data/DEBIAN/prerm" \
4090        "$pp_wrkdir/%preun.$cmp" "Pre-uninstall script for $cmp_full_name"\
4091        || exit $?
4092
4093    # Create postrm
4094    pp_deb_make_package_maintainer_script "$data/DEBIAN/postrm" \
4095        "$pp_wrkdir/%postun.$cmp" "Post-uninstall script for $cmp_full_name"\
4096        || exit $?
4097
4098    umask $old_umask
4099}
4100
4101pp_deb_make_data() {
4102    local _l t m o g f p st data
4103    local data share_doc owner group
4104    cmp=$1
4105    data=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
4106    cat $pp_wrkdir/%files.${cmp} | while read t m o g f p st; do
4107	if test x"$m" = x"-"; then
4108	    case "$t" in
4109		d) m=755;;
4110		f) m=644;;
4111	    esac
4112	fi
4113	test x"$o" = x"-" && o=root
4114	test x"$g" = x"-" && g=root
4115        case "$t" in
4116        f) # Files
4117           pp_deb_fakeroot install -D -o $o -g $g -m ${m} $pp_destdir/$p $data/$p;
4118           if [ x"$f" = x"v" ]
4119           then
4120               # File marked as "volatile". Assume this means it's a conffile
4121	       # TODO: check this as admins like modified conffiles to be left
4122	       #       behind
4123               echo "$p" >> $pp_wrkdir/%conffiles.$cmp
4124           fi;;
4125
4126        d) # Directories
4127           pp_deb_fakeroot install -m ${m} -o $o -g $g -d $data/$p;;
4128
4129        s) # Symlinks
4130           # Remove leading / from vars
4131           rel_p=`echo $p | sed s,^/,,`
4132           rel_st=`echo $st | sed s,^/,,`
4133           # TODO: we are always doing absolute links here. We should follow
4134	   # the debian policy of relative links when in the same top-level
4135	   # directory
4136           (cd $data; ln -sf $st $rel_p);;
4137	    *) pp_error "Unsupported data file type: $t";;
4138	esac
4139    done
4140
4141    # If no copyright file is present add one. This is a debian requirement.
4142    share_doc="/usr/share/doc/`pp_deb_cmp_full_name $cmp`"
4143    if [ ! -f "$data/$share_doc/copyright" ]
4144    then
4145        echo "${pp_deb_copyright:-$copyright}" > "$pp_wrkdir/copyright"
4146        install -D -m 644 "$pp_wrkdir/copyright" "$data/$share_doc/copyright"
4147    fi
4148
4149}
4150
4151pp_deb_makedeb () {
4152    local cmp
4153    local package_build_dir
4154
4155    cmp="$1"
4156
4157    package_build_dir=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
4158
4159    # Create package dir
4160    mkdir -p $package_build_dir
4161
4162    # Copy in data
4163    pp_deb_make_data $cmp ||
4164	pp_die "Could not make DEBIAN data files for $cmp"
4165
4166    # Make control files
4167    # must be done after copying data so conffiles are found
4168    pp_deb_make_DEBIAN $cmp ||
4169	pp_die "Could not make DEBIAN control files for $cmp"
4170
4171    # Create md5sums
4172    pp_deb_make_md5sums $cmp `(cd $package_build_dir;
4173	find . -name DEBIAN -prune -o -type f -print | sed "s,^\./,,")` ||
4174	    pp_die "Could not make DEBIAN md5sums for $cmp"
4175}
4176
4177pp_backend_deb () {
4178    local debname
4179
4180    # Munge description for control file inclusion
4181    pp_deb_munge_description
4182
4183    # Handle services
4184    pp_deb_handle_services $cmp
4185
4186    for cmp in $pp_components
4187    do
4188        debname=`pp_deb_name $cmp`
4189        pp_deb_makedeb $cmp
4190    done
4191
4192    . $pp_wrkdir/%fixup
4193
4194    for cmp in $pp_components
4195    do
4196        debname=`pp_deb_name $cmp`
4197	# Create debian package
4198	pp_debug "Building `pp_deb_cmp_full_name $cmp` -> $output"
4199	pp_deb_fakeroot dpkg-deb \
4200	    --build $pp_wrkdir/`pp_deb_cmp_full_name $cmp` \
4201	    $pp_wrkdir/$debname ||
4202		pp_error "failed to create $cmp package"
4203    done
4204}
4205
4206pp_backend_deb_cleanup () {
4207    # rm -rf $pp_wrkdir
4208    :
4209}
4210
4211pp_deb_name () {
4212    local cmp="${1:-run}"
4213    echo `pp_deb_cmp_full_name $cmp`"_"`pp_deb_version_final`"-${pp_deb_release:-1}_${pp_deb_arch}.deb"
4214}
4215pp_backend_deb_names () {
4216    for cmp in $pp_components
4217    do
4218        pp_deb_name $cmp
4219    done
4220}
4221
4222pp_backend_deb_install_script () {
4223    local cmp _cmp_full_name
4224
4225    echo "#!/bin/sh"
4226    pp_install_script_common
4227
4228    cat <<.
4229
4230        cmp_to_pkgname () {
4231            test x"\$*" = x"all" &&
4232                set -- $pp_components
4233            for cmp
4234            do
4235                case \$cmp in
4236.
4237    for cmp in $pp_components; do
4238         echo "$cmp) echo '`pp_deb_cmp_full_name $cmp`';;"
4239    done
4240    cat <<.
4241                *) usage;;
4242                esac
4243            done
4244        }
4245
4246
4247        cmp_to_pathname () {
4248            test x"\$*" = x"all" &&
4249                set -- $pp_components
4250            for cmp
4251            do
4252                case \$cmp in
4253.
4254    for cmp in $pp_components; do
4255         echo "$cmp) echo \${PP_PKGDESTDIR:-.}/'`pp_deb_name $cmp`';;"
4256    done
4257    cat <<.
4258                *) usage;;
4259		esac
4260            done
4261        }
4262
4263        test \$# -eq 0 && usage
4264        op="\$1"; shift
4265        case "\$op" in
4266            list-components)
4267                test \$# -eq 0 || usage \$op
4268                echo $pp_components
4269                ;;
4270            list-services)
4271                test \$# -eq 0 || usage \$op
4272                echo $pp_services
4273                ;;
4274            list-files)
4275                test \$# -ge 1 || usage \$op
4276                cmp_to_pathname "\$@"
4277                ;;
4278            install)
4279                test \$# -ge 1 || usage \$op
4280                dpkg --install \`cmp_to_pathname "\$@"\`
4281                ;;
4282            uninstall)
4283                test \$# -ge 1 || usage \$op
4284                dpkg --remove \`cmp_to_pkgname "\$@"\`; :
4285                ;;
4286            start|stop)
4287                test \$# -ge 1 || usage \$op
4288                ec=0
4289                for svc
4290                do
4291                    /etc/init.d/\$svc \$op || ec=1
4292                done
4293                exit \$ec
4294                ;;
4295            print-platform)
4296                test \$# -eq 0 || usage \$op
4297		echo "linux-${pp_deb_arch}"
4298		;;
4299            *)
4300                usage
4301                ;;
4302        esac
4303.
4304}
4305
4306pp_backend_deb_probe() {
4307    local arch distro release
4308
4309    pp_deb_detect_arch
4310
4311    # /etc/debian_version exists on Debian & Ubuntu, so it's no use
4312    # to us. Use lsb_release instead.
4313
4314    case `(lsb_release -is || echo no-lsb) 2>/dev/null` in
4315        Debian)
4316            distro=deb
4317	    ;;
4318        Ubuntu)
4319            distro=ubu
4320	    ;;
4321	no-lsb)
4322	    echo unknown-$pp_deb_arch_std
4323	    return 0
4324	    ;;
4325        *)
4326            distro=unknown
4327	    ;;
4328    esac
4329
4330    release=`lsb_release -rs`
4331
4332    # If release is not numeric, use the codename
4333    case $release in
4334        *[!.0-9r]*)
4335	    release=`lsb_release -cs`
4336	    case $release in
4337		buzz)
4338		    release="11"
4339		    ;;
4340		rex)
4341		    release="12"
4342		    ;;
4343		bo)
4344		    release="13"
4345		    ;;
4346		hamm)
4347		    release="20"
4348		    ;;
4349		slink)
4350		    release="21"
4351		    ;;
4352		potato)
4353		    release="22"
4354		    ;;
4355		woody)
4356		    release="30"
4357		    ;;
4358		sarge)
4359		    release="31"
4360		    ;;
4361		etch)
4362		    release="40"
4363		    ;;
4364		lenny)
4365		    release="50"
4366		    ;;
4367		squeeze)
4368		    release="60"
4369		    ;;
4370	    esac
4371	    ;;
4372	*)
4373	    # Remove trailing revision number and any dots
4374            release=`echo $release | cut -dr -f1 | tr -d .`
4375	    ;;
4376    esac
4377
4378    echo $distro$release-$pp_deb_arch_std
4379}
4380
4381pp_backend_deb_vas_platforms () {
4382    case "$pp_deb_arch_std" in
4383	x86_64)	echo "linux-x86_64.deb";; # DO NOT add linux-x86.deb here!!
4384	*86)	echo "linux-x86.deb";;
4385	*)	pp_die "unknown architecture ${pp_deb_arch_std}";;
4386    esac
4387}
4388pp_backend_deb_init_svc_vars () {
4389
4390    reload_signal=
4391    start_runlevels=${pp_deb_default_start_runlevels-"2 3 4 5"} # == lsb default-start
4392    stop_runlevels=${pp_deb_default_stop_runlevels-"0 1 6"}     # == lsb default-stop
4393    svc_description="${pp_deb_default_svc_description}" # == lsb short descr
4394    svc_process=
4395
4396    lsb_required_start='$local_fs $network'
4397    lsb_should_start=
4398    lsb_required_stop='$local_fs'
4399    lsb_description=
4400
4401    start_priority=50
4402    stop_priority=50            #-- stop_priority = 100 - start_priority
4403}
4404
4405pp_deb_service_make_init_script () {
4406    local svc=$1
4407    local script=/etc/init.d/$svc
4408    local out=$pp_destdir$script
4409    local _process _cmd
4410
4411    pp_add_file_if_missing $script run 755 v || return 0
4412
4413    #-- start out as an empty shell script
4414    cat <<-'.' >$out
4415	#!/bin/sh
4416.
4417
4418    #-- determine the process name from $cmd unless $svc_process is given
4419    set -- $cmd
4420    #_process=${svc_process:-"$1"} --? WTF
4421
4422    #-- construct a start command that builds a pid file if needed
4423    #-- the command name in /proc/[pid]/stat is limited to 15 characters 
4424    _cmd="$cmd";
4425    _cmd_path=`echo $cmd | cut -d" " -f1`
4426    _cmd_name=`basename $_cmd_path | cut -c1-15`
4427    _cmd_args=`echo $cmd | cut -d" " -f2-`
4428    test x"$_cmd_path" != x"$_cmd_args" || _cmd_args=
4429
4430    #-- generate the LSB init info
4431    cat <<-. >>$out
4432	### BEGIN INIT INFO
4433	# Provides: ${svc}
4434	# Required-Start: ${lsb_required_start}
4435	# Should-Start: ${lsb_should_start}
4436	# Required-Stop: ${lsb_required_stop}
4437	# Default-Start: ${start_runlevels}
4438	# Default-Stop: ${stop_runlevels}
4439	# Short-Description: ${svc_description:-no description}
4440	### END INIT INFO
4441	# Generated by PolyPackage ${pp_version}
4442	# ${copyright}
4443
4444.
4445
4446    if test x"${svc_description}" = x"${pp_deb_default_svc_description}"; then
4447        svc_description=
4448    fi
4449
4450    #-- write service-specific definitions
4451    cat <<. >>$out
4452NAME="${_cmd_name}"
4453DESC="${svc_description:-$svc service}"
4454USER="${user}"
4455GROUP="${group}"
4456PIDFILE="${pidfile}"
4457STOP_SIGNAL="${stop_signal}"
4458RELOAD_SIGNAL="${reload_signal}"
4459CMD="${_cmd}"
4460DAEMON="${_cmd_path}"
4461DAEMON_ARGS="${_cmd_args}"
4462SCRIPTNAME=${script}
4463.
4464
4465    #-- write the generic part of the init script
4466    cat <<'.' >>$out
4467
4468[ -x "$DAEMON" ] || exit 0
4469
4470[ -r /etc/default/$NAME ] && . /etc/default/$NAME
4471
4472[ -f /etc/default/rcS ] && . /etc/default/rcS
4473
4474. /lib/lsb/init-functions
4475
4476do_start()
4477{
4478	# Return
4479	#   0 if daemon has been started
4480	#   1 if daemon was already running
4481	#   2 if daemon could not be started
4482    if [ -n "$PIDFILE" ]
4483    then
4484        pidfile_opt="--pidfile $PIDFILE"
4485    else
4486        pidfile_opt="--make-pidfile --background --pidfile /var/run/$NAME.pid"
4487    fi
4488    if [ -n "$USER" ]
4489    then
4490        user_opt="--user $USER"
4491    fi
4492    if [ -n "$GROUP" ]
4493    then
4494        group_opt="--group $GROUP"
4495    fi
4496
4497	start-stop-daemon --start --quiet $pidfile_opt $user_opt --exec $DAEMON --test > /dev/null \
4498	    || return 1
4499
4500    # Note: there seems to be no way to tell whether the daemon will fork itself or not, so pass
4501    # --background for now
4502    start-stop-daemon --start --quiet $pidfile_opt $user_opt --exec $DAEMON -- \
4503    	$DAEMON_ARGS \
4504    	|| return 2
4505}
4506
4507do_stop()
4508{
4509	# Return
4510	#   0 if daemon has been stopped
4511	#   1 if daemon was already stopped
4512	#   2 if daemon could not be stopped
4513	#   other if a failure occurred
4514    if [ -n "$PIDFILE" ]
4515    then
4516        pidfile_opt="--pidfile $PIDFILE"
4517    else
4518        pidfile_opt="--pidfile /var/run/$NAME.pid"
4519    fi
4520    if [ -n "$USER" ]
4521    then
4522        user_opt="--user $USER"
4523    fi
4524    if [ -n $STOP_SIGNAL ]
4525    then
4526        signal_opt="--signal $STOP_SIGNAL"
4527    fi
4528	start-stop-daemon --stop --quiet $signal_opt --retry=TERM/30/KILL/5 $pidfile_opt --name $NAME
4529	RETVAL="$?"
4530	[ "$RETVAL" = 2 ] && return 2
4531	# Wait for children to finish too if this is a daemon that forks
4532	# and if the daemon is only ever run from this initscript.
4533	# If the above conditions are not satisfied then add some other code
4534	# that waits for the process to drop all resources that could be
4535	# needed by services started subsequently.  A last resort is to
4536	# sleep for some time.
4537	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
4538	[ "$?" = 2 ] && return 2
4539	# Many daemons don't delete their pidfiles when they exit.
4540	test -z $PIDFILE || rm -f $PIDFILE
4541	return "$RETVAL"
4542}
4543
4544do_reload() {
4545	#
4546	# If the daemon can reload its configuration without
4547	# restarting (for example, when it is sent a SIGHUP),
4548	# then implement that here.
4549	#
4550    if [ -n "$PIDFILE" ]
4551    then
4552        pidfile_opt="--pidfile $PIDFILE"
4553    else
4554        pidfile_opt="--pidfile /var/run/$NAME.pid"
4555    fi
4556    if [ -n "$RELOAD_SIGNAL" ]
4557    then
4558	    start-stop-daemon --stop --signal $RELOAD_SIGNAL --quiet $pidfile_opt --name $NAME
4559    fi
4560	return 0
4561}
4562
4563case "$1" in
4564  start)
4565	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
4566	do_start
4567	case "$?" in
4568		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
4569		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
4570	esac
4571	;;
4572  stop)
4573	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
4574	do_stop
4575	case "$?" in
4576		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
4577		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
4578	esac
4579	;;
4580  reload|force-reload)
4581    if [ -n "$RELOAD_SIGNAL" ]
4582    then
4583	    log_daemon_msg "Reloading $DESC" "$NAME"
4584	    do_reload
4585	    log_end_msg $?
4586    else
4587        # Do a restart instead
4588        "$0" restart
4589    fi
4590	;;
4591  restart)
4592	#
4593	# If the "reload" option is implemented then remove the
4594	# 'force-reload' alias
4595	#
4596	log_daemon_msg "Restarting $DESC" "$NAME"
4597	do_stop
4598	case "$?" in
4599	  0|1)
4600		do_start
4601		case "$?" in
4602			0) log_end_msg 0 ;;
4603			1) log_end_msg 1 ;; # Old process is still running
4604			*) log_end_msg 1 ;; # Failed to start
4605		esac
4606		;;
4607	  *)
4608	  	# Failed to stop
4609		log_end_msg 1
4610		;;
4611	esac
4612	;;
4613  *)
4614	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
4615	echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
4616	exit 3
4617	;;
4618esac
4619
4620:
4621.
4622    chmod 755 $out
4623}
4624pp_backend_deb_function() {
4625    case "$1" in
4626        pp_mkgroup) cat<<'.';;
4627	    /usr/sbin/groupmod "$1" 2>/dev/null && return 0
4628            /usr/sbin/groupadd "$1"
4629.
4630        pp_mkuser:depends) echo pp_mkgroup;;
4631        pp_mkuser) cat<<'.';;
4632	    pp_tmp_system=
4633	    id -u "$1" >/dev/null 2>/dev/null && return 0
4634	    # deb 3.1's useradd changed API in 4.0. Gah!
4635	    /usr/sbin/useradd --help 2>&1 | /bin/grep -q .--system &&
4636		pp_tmp_system=--system
4637	    pp_mkgroup "${2:-$1}" || return 1
4638	    /usr/sbin/useradd \
4639		-g "${2:-$1}" \
4640		-d "${3:-/nonexistent}" \
4641		-s "${4:-/bin/false}" \
4642		$pp_tmp_system \
4643		"$1"
4644.
4645        pp_havelib) cat<<'.';;
4646            for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
4647                test -r "$pp_tmp_dir/lib$1.so{$2:+.$2}" && return 0
4648            done
4649            return 1
4650.
4651    *) false;;
4652    esac
4653}
4654
4655pp_platforms="$pp_platforms kit"
4656
4657pp_backend_kit_detect () {
4658    test x"$1" = x"OSF1"
4659}
4660
4661pp_backend_kit_init () {
4662        pp_kit_name=
4663        pp_kit_package=
4664        pp_kit_desc=
4665        pp_kit_version=
4666        pp_kit_subset=
4667        pp_readlink_fn=pp_ls_readlink
4668        pp_kit_startlevels="2 3"
4669        pp_kit_stoplevels="0 2 3"
4670}
4671
4672pp_backend_kit () {
4673    typeset mi_file k_file svc outfile
4674    typeset desc
4675
4676    pp_backend_kit_names > /dev/null
4677
4678    if test -z "$pp_kit_desc"; then
4679        pp_kit_desc="$description"
4680    fi
4681
4682    mi_file="$pp_wrkdir/$pp_kit_subset.mi"
4683    k_file="$pp_wrkdir/$pp_kit_subset.k"
4684    scp_file="$pp_wrkdir/$pp_kit_subset.scp"
4685
4686    desc="${pp_kit_desc:-$description}"
4687
4688    cat <<-. >> $k_file
4689	NAME='$name'
4690	CODE=$pp_kit_name
4691	VERS=$pp_kit_version
4692	MI=$mi_file
4693	COMPRESS=0
4694	%%
4695	$pp_kit_subset	.	0	'$desc'
4696.
4697
4698    if test -n "$pp_services"; then
4699        for svc in $pp_services; do
4700            pp_kit_make_service $svc
4701            pp_prepend $pp_wrkdir/%preun.run <<-.
4702		/sbin/init.d/$svc stop
4703.
4704         done
4705    fi
4706
4707    pp_backend_kit_make_mi "$mi_file"
4708    pp_backend_kit_make_scp
4709    #rm -rf  $pp_wrkdir/kit_dest
4710    mkdir -p $pp_wrkdir/kit_dest
4711    pp_backend_kit_kits $k_file $pp_opt_destdir $pp_wrkdir/kit_dest
4712    tar cvf $pp_wrkdir/$pp_kit_subset.tar -C $pp_wrkdir/kit_dest .
4713    gzip -c $pp_wrkdir/$pp_kit_subset.tar > $pp_wrkdir/$pp_kit_subset.tar.gz
4714    #rm -rf $pp_wrkdir/$pp_kit_subset.tar $pp_wrkdir/scps
4715}
4716
4717pp_backend_kit_make_mi () {
4718    # XXX this information should go into the .inv files
4719    typeset t m o g f p st line dm
4720    while read t m o g f p st; do
4721        case $t in
4722            f|d)
4723                echo "0	.$p	$pp_kit_subset"
4724                echo "        chmod $m $p" >> $pp_wrkdir/%post.run
4725                if [ x"$o" = x"-" ] ; then
4726                    echo "        chown root $p" >> $pp_wrkdir/%post.run
4727                else
4728                    echo "        chown $o $p" >> $pp_wrkdir/%post.run
4729                fi
4730                if [ x"$g" = x"-" ] ; then
4731                    echo "        chgrp 0 $p" >> $pp_wrkdir/%post.run
4732                else
4733                    echo "        chgrp $g $p" >> $pp_wrkdir/%post.run
4734                fi
4735                ;;
4736            s)
4737                echo "        ln -s $st $p" >> $pp_wrkdir/%post.run
4738                echo "        rm -f $p" >> $pp_wrkdir/%preun.run
4739                ;;
4740         esac
4741    done < $pp_wrkdir/%files.run | sort -k3  |uniq > $1
4742}
4743
4744
4745pp_backend_kit_make_scp () {
4746    scpdir="$pp_wrkdir/scps"
4747    mkdir "$scpdir" && touch "$scpdir"/$pp_kit_subset.scp
4748    cat <<EOF >"$scpdir"/$pp_kit_subset.scp
4749
4750    . /usr/share/lib/shell/libscp
4751
4752    case "\$ACT" in
4753    PRE_L)
4754    STL_ScpInit
4755
4756
4757
4758    ;;
4759    POST_L)
4760        STL_ScpInit
4761        STL_LinkCreate
4762EOF
4763
4764    cat $pp_wrkdir/%post.run >>"$scpdir"/$pp_kit_subset.scp
4765    cat >>"$scpdir"/$pp_kit_subset.scp <<EOF
4766    ;;
4767    PRE_D)
4768        STL_ScpInit
4769        STL_LinkRemove
4770EOF
4771    cat $pp_wrkdir/%preun.run >>"$scpdir"/$pp_kit_subset.scp
4772    cat >>"$scpdir"/$pp_kit_subset.scp <<EOF
4773        ;;
4774    POST_D)
4775
4776        ;;
4777    C)
4778        STL_ScpInit
4779
4780        case "\$1" in
4781        INSTALL)
4782        echo "Installation of the \$_DESC (\$_SUB) subset is complete."
4783        ;;
4784    DELETE)
4785        ;;
4786    esac
4787
4788        ;;
4789    V)
4790
4791        ;;
4792    esac
4793
4794    exit 0
4795EOF
4796    chmod 744 "$scpdir"/$pp_kit_subset.scp
4797}
4798
4799
4800pp_backend_kit_cleanup () {
4801    :
4802}
4803
4804pp_backend_kit_names () {
4805    if test -z "$pp_kit_name"; then
4806        pp_warn "pp_kit_name not specified, using XXX"
4807        pp_kit_name=XXX
4808    fi
4809    case "$pp_kit_name" in
4810        ???) : ok;;
4811        *) pp_error "\$pp_kit_name $pp_kit_name must be three characters";;
4812    esac
4813    if test -z "$pp_kit_package"; then
4814        pp_warn "pp_kit_package not specified, using YYYY"
4815        pp_kit_package=YYYY
4816    fi
4817    if test -z "$pp_kit_version"; then
4818        pp_kit_version=`echo $version|tr -d '.a-zA-Z'`
4819    fi
4820    case "$pp_kit_version" in
4821        [0-9]) pp_kit_version="${pp_kit_version}00";;
4822        [0-9][0-9]) pp_kit_version="${pp_kit_version}0";;
4823        [0-9][0-9][0-9]) : ok;;
4824        *) pp_error "\$pp_kit_version $pp_kit_version must be three digits, ";;
4825    esac
4826    if test -z "$pp_kit_subset"; then
4827        pp_kit_subset="$pp_kit_name$pp_kit_package$pp_kit_version"
4828    fi
4829    echo "$pp_kit_subset.tar.gz"
4830}
4831
4832pp_backend_kit_install_script () {
4833    typeset pkgname platform
4834
4835    pkgname=`pp_backend_kit_names`
4836    platform="`pp_backend_kit_probe`"
4837
4838    echo "#!/bin/sh"
4839    pp_install_script_common
4840    cat <<.
4841
4842        cpt_to_tags () {
4843            test x"\$*" = x"all" && set -- $pp_components
4844            for cpt
4845            do
4846                echo "$name.\$cpt"
4847            done
4848        }
4849
4850        test \$# -eq 0 && usage
4851        op="\$1"; shift
4852
4853        case "\$op" in
4854            list-components)
4855                test \$# -eq 0 || usage \$op
4856                echo "$pp_components"
4857                ;;
4858            list-services)
4859                test \$# -eq 0 || usage \$op
4860                echo "$pp_services"
4861                ;;
4862            list-files)
4863                test \$# -ge 1 || usage \$op
4864                echo \${PP_PKGDESTDIR:-.}/$pkgname
4865                ;;
4866            install)
4867                test \$# -ge 1 || usage \$op
4868                verbose echo \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \`cpt_to_tags "\$@"\`
4869                #verbose swinstall -x verbose=0 -s \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \`cpt_to_tags "\$@"\`
4870                ;;
4871            uninstall)
4872                test \$# -ge 1 || usage \$op
4873                verbose echo \`cpt_to_tags "\$@"\`
4874                #verbose swremove -x verbose=0 \`cpt_to_tags "\$@"\`
4875                ;;
4876            start|stop)
4877                test \$# -ge 1 || usage \$op
4878                ec=0
4879                for svc
4880                do
4881                    verbose /sbin/init.d/\$svc \$op
4882                    [ \$? -eq 4 -o \$? -eq 0 ] || ec=1
4883                done
4884                exit \$ec
4885                ;;
4886            print-platform)
4887		echo "$platform"
4888		;;
4889            *)
4890                usage
4891                ;;
4892        esac
4893.
4894}
4895
4896pp_backend_kit_function () {
4897    case "$1" in
4898        pp_mkgroup) cat <<'.';;
4899            grep "^$1:" /etc/group >/dev/null ||
4900                /usr/sbin/groupadd $1
4901.
4902        pp_mkuser) cat <<'.';;
4903            eval user=\$$#
4904            grep "^$user:" /etc/passwd >/dev/null ||
4905                /usr/sbin/useradd -s /usr/bin/false "$@"
4906.
4907        pp_havelib) cat <<'.';;
4908            for dir in `echo /usr/lib${3+:$3} | tr : ' '`; do
4909                test -r "$dir/lib$1.${2-sl}" && return 0
4910            done
4911            return 1
4912.
4913        *) pp_error "unknown function request: $1";;
4914    esac
4915}
4916
4917pp_backend_kit_init_svc_vars () {
4918    :
4919}
4920
4921pp_backend_kit_probe () {
4922    echo tru64-`uname -r | sed 's/V\([0-9]*\)\.\([0-9]*\)/\1\2/'`
4923}
4924
4925pp_kit_service_group_script () {
4926    typeset grp svcs scriptpath out
4927    grp="$1"
4928    svcs="$2"
4929    scriptpath="/sbin/init.d/$grp"
4930    out="$pp_destdir$scriptpath"
4931
4932    pp_add_file_if_missing $scriptpath run 755 || return 0
4933
4934    cat <<-. > $out
4935	#!/sbin/sh
4936	# generated by pp $pp_version
4937	svcs="$svcs"
4938.
4939
4940cat <<-'.' >> $out
4941	#-- starts services in order.. stops them all if any break
4942	pp_start () {
4943	    undo=
4944	    for svc in $svcs; do
4945	        /sbin/init.d/$svc start
4946	        case $? in
4947	            0|4)
4948	                undo="$svc $undo"
4949	                ;;
4950	            *)
4951	                if test -n "$undo"; then
4952	                for svc in $undo; do
4953	                    /sbin/init.d/$svc stop
4954	                done
4955	                return 1
4956	                fi
4957	                ;;
4958	        esac
4959	    done
4960	    return 0
4961	}
4962
4963	#-- stops services in reverse
4964	pp_stop () {
4965	    reverse=
4966	        for svc in $svcs; do
4967	            reverse="$svc $reverse"
4968	        done
4969	        rc=0
4970	        for svc in $reverse; do
4971	            /sbin/init.d/$svc stop || rc=$?
4972	        done
4973	        return $rc
4974	}
4975
4976	case "$1" in
4977	    start_msg) echo "Starting $svcs";;
4978	stop_msg)  echo "Stopping $svcs";;
4979	start)     pp_start;;
4980	stop)      pp_stop;;
4981	*)         echo "usage: $0 {start|stop|start_msg|stop_msg}"
4982	    exit 1;;
4983	esac
4984.
4985}
4986
4987pp_kit_service_script () {
4988    typeset svc scriptpath out
4989
4990    svc="$1"
4991    scriptpath="/sbin/init.d/$svc"
4992
4993    pp_load_service_vars "$svc"
4994
4995    test -n "$user" -a x"$user" != x"root" &&
4996    cmd="SHELL=/usr/bin/sh /usr/bin/su $user -c \"exec `echo $cmd | sed -e 's,[$\\\`],\\&,g'`\""
4997    if test -z "$pidfile"; then
4998        pidfile="/var/run/$svc.pid"
4999        cmd="$cmd & echo \$! > \$pidfile"
5000    fi
5001
5002    pp_add_file_if_missing $scriptpath run 755
5003
5004    cat <<-. > $pp_destdir$scriptpath
5005	svc="$svc"
5006	pidfile="$pidfile"
5007
5008	pp_start () {
5009	    $cmd
5010	}
5011.
5012    cat <<-'.' >>$pp_destdir$scriptpath
5013	    pp_stop () {
5014	        if test ! -s "$pidfile"; then
5015	            echo "Unable to stop $svc (no pid file)"
5016	                return 1
5017	        else
5018	            read pid < "$pidfile"
5019	            if kill -0 "$pid" 2>/dev/null; then
5020	                if kill -${stop_signal:-TERM} "$pid"; then
5021	                    rm -f "$pidfile"
5022	                    return 0
5023	                else
5024	                    echo "Unable to stop $svc"
5025	                    return 1
5026	                fi
5027	            else
5028	                rm -f "$pidfile"
5029	                return 0
5030	            fi
5031	        fi
5032	    }
5033
5034	    pp_running () {
5035	        if test ! -s "$pidfile"; then
5036	            return 1
5037	        else
5038	            read pid < "$pidfile"
5039	            kill -0 "$pid" 2>/dev/null
5040	        fi
5041	    }
5042	    case "$1" in
5043	        start_msg) echo "Starting the $svc service";;
5044	        stop_msg)  echo "Stopping the $svc service";;
5045	        start)
5046	            if pp_running; then
5047	                echo "$svc already running";
5048	                exit 0
5049	            elif pp_start; then
5050	                echo "$svc started";
5051	# rc(1M) says we should exit 4, but nobody expects it!
5052	                exit 0
5053	            else
5054	                exit 1
5055	            fi
5056	            ;;
5057	        stop)
5058	            if pp_stop; then
5059	                echo "$svc stopped";
5060	                exit 0
5061	            else
5062	                exit 1
5063	            fi
5064	            ;;
5065	        *) echo "usage: $0 {start|stop|start_msg|stop_msg}"
5066	           exit 1
5067	           ;;
5068	    esac
5069.
5070}
5071
5072pp_kit_make_service () {
5073    typeset level priority startlevels stoplevels
5074    typeset svc svcvar
5075
5076    svc="$1"
5077    svcvar=`pp_makevar $svc`
5078
5079    #-- don't do anything if the script exists
5080    if test -s "$pp_destdir/sbin/init.d/$svc"; then
5081        pp_error "$pp_destdir/sbin/init.d/$svc exists"
5082        return
5083    fi
5084
5085    # symlink the script, depending on the priorities chosen
5086    eval priority='${pp_kit_priority_'$svcvar'}'
5087    test -z "$priority" && priority="${pp_kit_priority:-50}"
5088
5089    eval startlevels='${pp_kit_startlevels_'$svcvar'}'
5090    test -z "$startlevels" && startlevels="$pp_kit_startlevels"
5091
5092    eval stoplevels='${pp_kit_stoplevels_'$svcvar'}'
5093    test -z "$stoplevels" && stoplevels="$pp_kit_stoplevels"
5094
5095    # create the script and config file
5096    pp_kit_service_script $svc
5097
5098    # fix the priority up
5099    case "$priority" in
5100        ???) :;;
5101        ??) priority=0$priority;;
5102        ?) priority=00$priority;;
5103    esac
5104
5105    if test x"$stoplevels" = x"auto"; then
5106        stoplevels=
5107        test -z "$startlevels" || for level in $startlevels; do
5108            stoplevels="$stoplevels `expr $level - 1`"
5109        done
5110    fi
5111
5112    # create the symlinks
5113    test -z "$startlevels" || for level in $startlevels; do
5114        echo "        ln -s /sbin/init.d/$svc /sbin/rc$level.d/S$priority$svc" >>$pp_wrkdir/%post.run
5115        echo "        rm /sbin/rc$level.d/S$priority$svc" >>$pp_wrkdir/%preun.run
5116    done
5117    test -z "$stoplevels" || for level in $stoplevels; do
5118        echo "        ln -s /sbin/init.d/$svc /sbin/rc$level.d/K$priority$svc" >>$pp_wrkdir/%post.run
5119        echo "        rm -f /sbin/rc$level.d/K$priority$svc" >>$pp_wrkdir/%preun.run
5120    done
5121}
5122
5123
5124
5125
5126pp_backend_kit_sizes () {
5127    awk '
5128    BEGIN { root = usr = var = 0; }
5129    {
5130        if (substr($9, 1, 1) != "l")
5131            if (substr($10, 1, 6) == "./var/")
5132                var += $2;
5133            else if (substr($10, 1, 10) == "./usr/var/")
5134                var += $2
5135            else if (substr($10, 1, 6) == "./usr/")
5136                usr += $2
5137            else
5138                root += $2
5139    }
5140    END { printf "%d\t%d\t%d", root, usr, var }
5141    ' "$@"
5142}
5143
5144pp_kit_kits_global () {
5145    line=`sed -n '/^%%/q;/^'$2'=/{s/^'$2'=//p;q;}' <"$1"`
5146    test -z "$line" && return 1
5147    eval "echo $line"
5148    :
5149}
5150
5151pp_backend_kit_kits () {
5152    typeset KITFILE FROMDIR TODIR
5153    typeset SCPDIR
5154
5155    SCPDIR="$pp_wrkdir/scps"
5156
5157    PATH="/usr/lbin:/usr/bin:/etc:/usr/ucb:$PATH"; export PATH # XXX
5158    #umask 2 # XXX
5159
5160    test $# -ge 3 || pp_die "pp_backend_kit_kits: too few arguments"
5161    KITFILE="$1"; shift
5162    FROMDIR="$1"; shift
5163    TODIR="$1"; shift
5164
5165    test -f "$KITFILE" || pp_die "$KITFILE not found"
5166    test -d "$FROMDIR" || pp_die "$FROMDIR not found"
5167    test -d "$TODIR"   || pp_die "$TODIR not found"
5168
5169    INSTCTRL="$TODIR/instctrl"
5170    mkdir -p "$INSTCTRL" || pp_die "cannot create instctrl directory"
5171    chmod 775 "$INSTCTRL"
5172
5173    grep "%%" $KITFILE > /dev/null || pp_die "no %% in $KITFILE"
5174
5175    typeset NAME CODE VERS MI ROOT COMPRESS
5176    typeset S_LIST ALLSUBS
5177
5178    NAME=`pp_kit_kits_global "$KITFILE" NAME` || pp_die "no NAME in $KITFILE"
5179    CODE=`pp_kit_kits_global "$KITFILE" CODE` || pp_die "no CODE in $KITFILE"
5180    VERS=`pp_kit_kits_global "$KITFILE" VERS` || pp_die "no VERS in $KITFILE"
5181    MI=`pp_kit_kits_global "$KITFILE" MI` || pp_die "no MI in $KITFILE"
5182    ROOT=`pp_kit_kits_global "$KITFILE" ROOT`
5183    COMPRESS=`pp_kit_kits_global "$KITFILE" COMPRESS`
5184
5185    test -f "$MI" || pp_die "Inventory file $MI not found"
5186
5187    case "$ROOT" in
5188    *ROOT)
5189        test -f "$TODIR/$ROOT" ||
5190            pp_die "Root image $ROOT not found in $TODIR" ;;
5191    esac
5192
5193    ALLSUBS=`awk 'insub==1 {print $1} /^%%/ {insub=1}' <"$KITFILE"`
5194    test $# -eq 0 && set -- $ALLSUBS
5195
5196    pp_debug "Creating $# $NAME subsets."
5197    pp_debug "ALLSUBS=<$ALLSUBS>"
5198
5199    if test x"$COMPRESS" = x"1"; then
5200        COMPRESS=:
5201    else
5202        COMPRESS=false
5203    fi
5204
5205    #rm -f *.ctrl Volume*
5206
5207    for SUB
5208    do
5209        test -z "$SUB" && pp_die "SUB is empty"
5210
5211        typeset INV CTRL ROOTSIZE USRSIZE VARSIZE TSSUB
5212	#rm -f Volume*
5213	case $SUB in
5214            .*) :;;
5215	    *)  pp_verbose rm -f "$TODIR/$SUB"* "$INSTCTRL/$SUB"*;;
5216        esac
5217
5218        TSSUB="$pp_wrkdir/ts.$SUB"
5219
5220	pp_debug "kits: Subset $SUB"
5221
5222	INV="$SUB.inv"
5223	CTRL="$SUB.ctrl"
5224	pp_debug "kits: Generating media creation information..."
5225
5226        # Invcutter takes as input
5227        #   SUB dir/path
5228        # and generates stl_inv(4) files, like this
5229        #   f 0 00000 0 0 100644 2/11/09 010 f dir/path none SUB
5230	grep "	$SUB\$" "$MI" |
5231            pp_verbose /usr/lbin/invcutter \
5232                -v "$VERS" -f "$FROMDIR" > "$INSTCTRL/$INV" ||
5233            pp_die "failed to create $INSTCTRL/$INV"
5234        chmod 664 "$INSTCTRL/$INV"
5235
5236        pp_backend_kit_sizes "$INSTCTRL/$INV" > "$pp_wrkdir/kit.sizes"
5237        read ROOTSIZE USRSIZE VARSIZE < "$pp_wrkdir/kit.sizes"
5238
5239        # Prefix each line with $FROMDIR. This will be stripped
5240        awk '$1 != "d" {print from $10}' from="$FROMDIR/" \
5241            > "$TSSUB" < "$INSTCTRL/$INV" ||
5242            pp_die "failed"
5243
5244        NVOLS=0
5245
5246	pp_debug "kits: Creating $SUB control file..."
5247
5248        sed '1,/^%%/d;/^'"$SUB"'/{p;q;}' < "$KITFILE" > "$pp_wrkdir/kit.line"
5249        read _SUB _IGNOR DEPS FLAGS DESC < "$pp_wrkdir/kit.line"
5250        if test -z "$_SUB"; then
5251            pp_warn "No such subset $SUB in $KITFILE"
5252            continue
5253	fi
5254        DEPS=`echo $DEPS | tr '|' ' '`
5255        case $FLAGS in
5256            FLGEXP*) pp_verbose FLAGS='"${'"$FLAGS"'}"' ;;
5257        esac
5258        case $DESC in
5259            *%*) DESC=`echo $DESC|awk -F% '{printf "%-36s%%%s\n", $1, $2}'`;;
5260        esac
5261
5262	cat > "$INSTCTRL/$CTRL" <<-.
5263		NAME='$NAME $SUB'
5264		DESC=$DESC
5265		ROOTSIZE=$ROOTSIZE
5266		USRSIZE=$USRSIZE
5267		VARSIZE=$VARSIZE
5268		NVOLS=1:$NVOLS
5269		MTLOC=1:$TLOC
5270		DEPS="$DEPS"
5271		FLAGS=$FLAGS
5272.
5273        chmod 664 "$INSTCTRL/$CTRL"
5274
5275	pp_debug "kits: Making tar image"
5276
5277	pp_verbose tar cfPR "$TODIR/$SUB" "$FROMDIR/" "$TSSUB" ||
5278             pp_error "problem creating kit file"
5279
5280        if $COMPRESS; then
5281            pp_debug "kits: Compressing"
5282            (cd "$TODIR" && compress -f -v "$SUB") ||
5283                pp_die "problem compressing $TODIR/$SUB"
5284            SPC=`expr $SUB : '\(...\).*'`    # first three characters
5285            SVC=`expr $SUB : '.*\(...\)'`    # last three characters
5286            : > "$INSTCTRL/$SPC$SVC.comp"
5287            chmod 664 "$INSTCTRL/$SPC$SVC.comp"
5288            pp_debug "kits: Padding compressed file to 10kB" # wtf?
5289            rm -f "$TODIR/$SUB"
5290            pp_verbose \
5291            dd if="$TODIR/$SUB.Z" of="$TODIR/$SUB" bs=10k conv=sync ||
5292                pp_die "problem moving compressed file"
5293            rm -f "$TODIR/$SUB.Z"
5294        fi
5295        chmod 664 "$TODIR/$SUB"
5296
5297	if test -f "$SCPDIR/$SUB.scp"; then
5298		cp "$SCPDIR/$SUB.scp" "$INSTCTRL/$SUB.scp"
5299                chmod 755 "$INSTCTRL/$SUB.scp"
5300	else
5301		pp_debug "kits: null subset control program for $SUB"
5302		: > "$INSTCTRL/$SUB.scp"
5303		chmod 744 "$INSTCTRL/$SUB.scp"
5304	fi
5305
5306        pp_debug "kits: Finished creating media image for $SUB"
5307    done
5308
5309    pp_debug "kits: Creating $CODE.image"
5310
5311    case "$ROOT" in
5312    *ROOT)	ALLSUBS="$ROOT $ALLSUBS"
5313                ;;
5314    esac
5315
5316    (cd "$TODIR" && sum $ALLSUBS) > "$INSTCTRL/$CODE.image"
5317    chmod 664 "$INSTTRL/$CODE.image"
5318    pp_debug "kits: Creating INSTCTRL"
5319    (cd "$INSTCTRL" && tar cpvf - *) > "$TODIR/INSTCTRL"
5320    chmod 664 "$TODIR/INSTCTRL"
5321    cp "$INSTCTRL/$CODE.image" "$TODIR/$CODE.image"
5322    chmod 664 "$TODIR/$CODE.image"
5323
5324    pp_debug "kits: Media image production complete"
5325}
5326
5327pp_platforms="$pp_platforms rpm"
5328
5329pp_backend_rpm_detect () {
5330    test x"$1" = x"Linux" -a ! -f /etc/debian_version
5331}
5332
5333pp_backend_rpm_init () {
5334
5335    pp_rpm_version=
5336    pp_rpm_summary=
5337    pp_rpm_description=
5338    pp_rpm_group="Applications/Internet"
5339    pp_rpm_license="Unspecified"
5340    pp_rpm_vendor=
5341    pp_rpm_url=
5342    pp_rpm_packager=
5343    pp_rpm_provides=
5344    pp_rpm_requires=
5345    pp_rpm_release=
5346    pp_rpm_epoch=
5347    pp_rpm_dev_group="Development/Libraries"
5348    pp_rpm_dbg_group="Development/Tools"
5349    pp_rpm_doc_group="Documentation"
5350    pp_rpm_dev_description=
5351    pp_rpm_dbg_description=
5352    pp_rpm_doc_description=
5353    pp_rpm_dev_requires=
5354    pp_rpm_dbg_requires=
5355    pp_rpm_doc_requires=
5356    pp_rpm_dev_provides=
5357    pp_rpm_dbg_provides=
5358    pp_rpm_doc_provides=
5359
5360    pp_rpm_dbg_pkgname=debug
5361    pp_rpm_dev_pkgname=devel
5362    pp_rpm_doc_pkgname=doc
5363
5364    pp_rpm_defattr_uid=root
5365    pp_rpm_defattr_gid=root
5366
5367    pp_rpm_detect_arch
5368    pp_rpm_detect_distro
5369    pp_rpm_rpmbuild=`pp_rpm_detect_rpmbuild`
5370
5371    # SLES8 doesn't always come with readlink
5372    test -x /usr/bin/readlink -o -x /bin/readlink ||
5373        pp_readlink_fn=pp_ls_readlink
5374}
5375
5376pp_rpm_detect_arch () {
5377    pp_rpm_arch=auto
5378
5379    #-- Find the default native architecture that RPM is configured to use
5380    cat <<-. >$pp_wrkdir/dummy.spec
5381	Name: dummy
5382	Version: 1
5383	Release: 1
5384	Summary: dummy
5385	Group: ${pp_rpm_group}
5386	License: ${pp_rpm_license}
5387	%description
5388	dummy
5389.
5390    $pp_opt_debug && cat $pp_wrkdir/dummy.spec
5391    pp_rpm_arch_local=`rpm -q --qf '%{arch}\n' --specfile $pp_wrkdir/dummy.spec`
5392    rm $pp_wrkdir/dummy.spec
5393
5394    #-- Ask the kernel what machine architecture is in use
5395    local arch
5396    for arch in "`uname -m`" "`uname -p`"; do
5397	case "$arch" in
5398	    i?86)
5399		pp_rpm_arch_std=i386
5400		break
5401		;;
5402	    x86_64|ppc|ppc64|ia64|s390|s390x)
5403		pp_rpm_arch_std="$arch"
5404		break
5405		;;
5406	    powerpc)
5407		# Probably AIX
5408		case "`/usr/sbin/lsattr -El proc0 -a type -F value`" in
5409		    PowerPC_POWER*)	pp_rpm_arch_std=ppc64;;
5410		    *)			pp_rpm_arch_std=ppc;;
5411		esac
5412		break
5413		;;
5414	    *)	pp_rpm_arch_std=unknown
5415		;;
5416	esac
5417    done
5418
5419    #-- Later on, when files are processed, we use 'file' to determine
5420    #   what platform ABIs are used. This is used when pp_rpm_arch == auto
5421    pp_rpm_arch_seen=
5422}
5423
5424pp_rpm_detect_distro () {
5425    pp_rpm_distro=
5426    if test -f /etc/whitebox-release; then
5427       pp_rpm_distro=`awk '
5428          /^White Box Enterprise Linux release/ { print "wbel" $6; exit; }
5429       ' /etc/whitebox-release`
5430    elif test -f /etc/mandrakelinux-release; then
5431       pp_rpm_distro=`awk '
5432          /^Mandrakelinux release/ { print "mand" $3; exit; }
5433       ' /etc/mandrake-release`
5434    elif test -f /etc/mandrake-release; then
5435       pp_rpm_distro=`awk '
5436          /^Linux Mandrake release/ { print "mand" $4; exit; }
5437          /^Mandrake Linux release/ { print "mand" $4; exit; }
5438       ' /etc/mandrake-release`
5439    elif test -f /etc/fedora-release; then
5440       pp_rpm_distro=`awk '
5441          /^Fedora Core release/ { print "fc" $4; exit; }
5442          /^Fedora release/ { print "f" $3; exit; }
5443       ' /etc/fedora-release`
5444    elif test -f /etc/redhat-release; then
5445       pp_rpm_distro=`awk '
5446          /^Red Hat Enterprise Linux/ { print "rhel" $7; exit; }
5447          /^CentOS release/           { print "centos" $3; exit; }
5448          /^CentOS Linux release/     { print "centos" $4; exit; }
5449          /^Red Hat Linux release/    { print "rh" $5; exit; }
5450       ' /etc/redhat-release`
5451    elif test -f /etc/SuSE-release; then
5452       pp_rpm_distro=`awk '
5453          /^SuSE Linux [0-9]/ { print "suse" $3; exit; }
5454          /^SUSE LINUX [0-9]/ { print "suse" $3; exit; }
5455          /^openSUSE [0-9]/   { print "suse" $2; exit; }
5456          /^S[uU]SE Linux Enterprise Server [0-9]/ { print "sles" $5; exit; }
5457          /^S[uU]SE LINUX Enterprise Server [0-9]/ { print "sles" $5; exit; }
5458          /^SuSE SLES-[0-9]/  { print "sles" substr($2,6); exit; }
5459       ' /etc/SuSE-release`
5460    elif test -f /etc/pld-release; then
5461       pp_rpm_distro=`awk '
5462          /^[^ ]* PLD Linux/ { print "pld" $1; exit; }
5463       ' /etc/pld-release`
5464    elif test X"`uname -s 2>/dev/null`" = X"AIX"; then
5465	local r v
5466	r=`uname -r`
5467	v=`uname -v`
5468	pp_rpm_distro="aix$v$r"
5469    fi
5470    pp_rpm_distro=`echo $pp_rpm_distro | tr -d .`
5471    test -z "$pp_rpm_distro" &&
5472       pp_warn "unknown distro"
5473}
5474
5475pp_rpm_detect_rpmbuild () {
5476    local cmd
5477    for cmd in rpmbuild rpm; do
5478        if `which $cmd > /dev/null 2>&1`; then
5479            echo $cmd
5480            return 0
5481        fi
5482    done
5483
5484    pp_error "Could not find rpmbuild"
5485    # Default to `rpmbuild` in case it magically appears
5486    echo rpmbuild
5487    return 1
5488}
5489
5490pp_rpm_label () {
5491    local label arg
5492    label="$1"; shift
5493    for arg
5494    do
5495        test -z "$arg" || echo "$label: $arg"
5496    done
5497}
5498
5499pp_rpm_writefiles () {
5500    local _l t m o g f p st fo farch
5501    while read t m o g f p st; do
5502        _l="$p"
5503	test $t = d && _l="%dir ${_l%/}/"
5504        if test x"$m" = x"-"; then
5505            case "$t" in
5506                d) m=755;;
5507                f) m=644;;
5508            esac
5509        fi
5510        test x"$o" = x"-" && o="${pp_rpm_defattr_uid:-root}"
5511        test x"$g" = x"-" && g="${pp_rpm_defattr_gid:-root}"
5512	_l="%attr($m,$o,$g) $_l"
5513
5514	if test "$t" = "f" -a x"$pp_rpm_arch" = x"auto"; then
5515	    fo=`file "${pp_destdir}$p" 2>/dev/null`
5516	    #NB: The following should match executables and shared objects,
5517	    #relocatable objects. It will not match .a files however.
5518	    case "$fo" in
5519		*": ELF 32-bit LSB "*", Intel 80386"*)
5520		    farch=i386;;
5521		*": ELF 64-bit LSB "*", AMD x86-64"*|\
5522		*": ELF 64-bit LSB "*", x86-64"*)
5523		    farch=x86_64;;
5524		*": ELF 32-bit MSB "*", PowerPC"*)
5525		    farch=ppc;;
5526		*": ELF 64-bit MSB "*", 64-bit PowerPC"*)
5527		    farch=ppc64;;
5528		*": ELF 64-bit LSB "*", IA-64"*)
5529		    farch=ia64;;
5530		*": ELF 32-bit MSB "*", IBM S/390"*)
5531		    farch=s390;;
5532		*": ELF 64-bit MSB "*", IBM S/390"*)
5533		    farch=s390x;;
5534		*"executable (RISC System/6000)"*)
5535		    farch=ppc;;
5536		*"64-bit XCOFF executable"*)
5537		    farch=ppc64;;
5538		*" ELF "*)
5539		    farch=ELF;;
5540		*)
5541		    farch=noarch;;
5542	    esac
5543	    # If file(1) doesn't provide enough info, try readelf(1)
5544	    if test "$farch" = "ELF"; then
5545		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`
5546		case "$fo" in
5547		    "ELF32 Intel 80386")
5548			farch=i386;;
5549		    "ELF64 "*[xX]"86-64")
5550			farch=x86_64;;
5551		    "ELF32 PowerPC")
5552			farch=ppc;;
5553		    "ELF64 PowerPC"*)
5554			farch=ppc64;;
5555		    "ELF64 IA-64")
5556			farch=ia64;;
5557		    "ELF32 IBM S/390")
5558			farch=s390;;
5559		    "ELF64 IBM S/390")
5560			farch=s390x;;
5561		    *)
5562			farch=noarch;;
5563		esac
5564	    fi
5565	    pp_debug "file: $fo -> $farch"
5566	    test x"$farch" = x"noarch" || pp_add_to_list pp_rpm_arch_seen $farch
5567	fi
5568
5569	case $f in *v*) _l="%config(noreplace) $_l";; esac
5570	echo "$_l"
5571    done
5572    echo
5573}
5574
5575pp_rpm_subname () {
5576    case "$1" in
5577        run) : ;;
5578        dbg) echo "${2}${pp_rpm_dbg_pkgname}";;
5579        dev) echo "${2}${pp_rpm_dev_pkgname}";;
5580        doc) echo "${2}${pp_rpm_doc_pkgname}";;
5581        *)   pp_error "unknown component '$1'";
5582    esac
5583}
5584
5585pp_rpm_depend () {
5586    local _name _vers
5587    while read _name _vers; do
5588        case "$_name" in ""| "#"*) continue ;; esac
5589        echo "Requires: $_name ${_vers:+>= $_vers}"
5590    done
5591}
5592
5593pp_rpm_conflict () {
5594    local _name _vers
5595    while read _name _vers; do
5596        case "$_name" in ""| "#"*) continue ;; esac
5597        echo "Conflicts: $_name ${_vers:+>= $_vers}"
5598    done
5599}
5600
5601pp_rpm_override_requires () {
5602    local orig_find_requires
5603
5604    if test -z "$pp_rpm_depend_filter_cmd"; then
5605	return 0
5606    fi
5607
5608    orig_find_requires=`rpm --eval '%{__find_requires}'`
5609    cat << EOF > "$pp_wrkdir/filtered-find-requires"
5610$orig_find_requires \$@ | $pp_rpm_depend_filter_cmd
5611EOF
5612    chmod +x "$pp_wrkdir/filtered-find-requires"
5613    echo "%define __find_requires $pp_wrkdir/filtered-find-requires"
5614    # Might be necessary for old versions of RPM? Not for 4.4.2.
5615    #echo "%define _use_internal_dependency_generator 0"
5616}
5617
5618pp_backend_rpm () {
5619    local cmp specfile _summary _group _desc _pkg _subname svc
5620
5621	specfile=$pp_wrkdir/$name.spec
5622        : > $specfile
5623
5624        #-- force existence of a 'run' component
5625        pp_add_component run
5626        : >> $pp_wrkdir/%files.run
5627
5628	if test -z "$pp_rpm_arch"; then
5629            pp_error "Unknown RPM architecture"
5630            return 1
5631        fi
5632
5633	#-- Write the header components of the RPM spec file
5634	cat <<-. >>$specfile
5635		Name: ${pp_rpm_name:-$name}
5636		Version: ${pp_rpm_version:-$version}
5637		Release: ${pp_rpm_release:-1}
5638		Summary: ${pp_rpm_summary:-$summary}
5639		Group:   ${pp_rpm_group}
5640		License: ${pp_rpm_license}
5641.
5642	if test -n "$pp_rpm_url"; then
5643	    pp_rpm_label "URL"  "$pp_rpm_url"               >>$specfile
5644	fi
5645	pp_rpm_label "Vendor"   "${pp_rpm_vendor:-$vendor}" >>$specfile
5646	pp_rpm_label "Packager" "$pp_rpm_packager"          >>$specfile
5647	pp_rpm_label "Provides" "$pp_rpm_provides"          >>$specfile
5648	pp_rpm_label "Requires" "$pp_rpm_requires"          >>$specfile
5649
5650	test -n "$pp_rpm_serial" && pp_warn "pp_rpm_serial deprecated"
5651	if test -n "$pp_rpm_epoch"; then
5652	    #-- Epoch was introduced in RPM 2.5.6
5653	    case `$pp_rpm_rpmbuild --version 2>/dev/null` in
5654		1.*|2.[0-5].*|2.5.[0-5])
5655		    pp_rpm_label "Serial" $pp_rpm_epoch >>$specfile;;
5656		*)
5657		    pp_rpm_label "Epoch" $pp_rpm_epoch >>$specfile;;
5658	    esac
5659	fi
5660
5661        if test -n "$pp_rpm_requires"; then
5662            pp_rpm_label "Requires" "$pp_rpm_requires" >>$specfile
5663        elif test -s $pp_wrkdir/%depend.run; then
5664            pp_rpm_depend < $pp_wrkdir/%depend.run >> $specfile
5665        fi
5666        if test -s $pp_wrkdir/%conflict.run; then
5667            pp_rpm_conflict < $pp_wrkdir/%conflict.run >> $specfile
5668        fi
5669
5670	pp_rpm_override_requires >> $specfile
5671
5672	cat <<-. >>$specfile
5673
5674		%description
5675		${pp_rpm_description:-$description}
5676.
5677
5678	for cmp in $pp_components; do
5679		case $cmp in
5680		   run) continue;;
5681		   dev) _summary="development tools for $pp_rpm_summary"
5682		   	_group="$pp_rpm_dev_group"
5683			_desc="${pp_rpm_dev_description:-Development libraries for $name. $pp_rpm_description.}"
5684		   	;;
5685		   doc) _summary="documentation for $pp_rpm_summary"
5686		   	_group="$pp_rpm_doc_group"
5687			_desc="${pp_rpm_doc_description:-Documentation for $name. $pp_rpm_description.}"
5688		   	;;
5689		   dbg) _summary="diagnostic tools for $pp_rpm_summary"
5690		   	_group="$pp_rpm_dbg_group"
5691			_desc="${pp_rpm_dbg_description:-Diagnostic tools for $name.}"
5692		   	;;
5693		esac
5694
5695                _subname=`pp_rpm_subname $cmp`
5696		cat <<-.
5697
5698			%package $_subname
5699			Summary: $name $_summary
5700			Group: $_group
5701.
5702                eval '_pkg="$pp_rpm_'$cmp'_requires"'
5703                if test -n "$_pkg"; then
5704                    eval pp_rpm_label Requires ${pp_rpm_name:-$name} $_pkg
5705                elif test -s $pp_wrkdir/%depend.$cmp; then
5706                    pp_rpm_depend < $pp_wrkdir/%depend.$cmp >> $specfile
5707                fi
5708                if test -s $pp_wrkdir/%conflict.$cmp; then
5709                    pp_rpm_conflict < $pp_wrkdir/%conflict.$cmp >> $specfile
5710                fi
5711
5712                eval '_pkg="$pp_rpm_'$cmp'_provides"'
5713		eval pp_rpm_label Provides $_pkg
5714
5715		cat <<-.
5716
5717			%description $_subname
5718			$_desc
5719.
5720	done >>$specfile
5721
5722        #-- NB: we don't put any %prep, %build or %install RPM sections
5723	#   into the spec file.
5724
5725        #-- add service start/stop code
5726        if test -n "$pp_services"; then
5727            pp_rpm_service_install_common >> $pp_wrkdir/%post.run
5728
5729            #-- record the uninstall commands in reverse order
5730            for svc in $pp_services; do
5731                pp_load_service_vars $svc
5732
5733                pp_rpm_service_make_init_script $svc
5734
5735                #-- append %post code to install the svc
5736                pp_rpm_service_install $svc >> $pp_wrkdir/%post.run
5737
5738                #-- prepend %preun code to uninstall svc
5739                # (use files in case vars are modified)
5740                pp_rpm_service_remove $svc | pp_prepend $pp_wrkdir/%preun.run
5741            done
5742            pp_rpm_service_remove_common | pp_prepend $pp_wrkdir/%preun.run
5743        fi
5744
5745	# make convenience service groups
5746        if test -n "$pp_service_groups"; then
5747	    for grp in $pp_service_groups; do
5748		pp_rpm_service_group_make_init_script \
5749		    $grp "`pp_service_get_svc_group $grp`"
5750	    done
5751	fi
5752
5753	#-- Write the RPM %file sections
5754        #   (do this after services, since services adds to %files.run)
5755	for cmp in $pp_components; do
5756            _subname=`pp_rpm_subname $cmp`
5757
5758            if test -s $pp_wrkdir/%check.$cmp; then
5759                echo ""
5760                echo "%pre $_subname"
5761                cat $pp_wrkdir/%check.$cmp
5762                echo :   # causes script to exit true by default
5763            fi
5764
5765            if test -s $pp_wrkdir/%files.$cmp; then
5766                echo ""
5767                echo "%files $_subname"
5768                pp_rpm_writefiles < $pp_wrkdir/%files.$cmp
5769            fi
5770
5771            if test -n "$pp_rpm_ghost"; then
5772                for ghost in $pp_rpm_ghost; do
5773                    echo "%ghost $ghost"
5774                done
5775            fi
5776
5777            if test -s $pp_wrkdir/%pre.$cmp; then
5778                echo ""
5779                echo "%pre $_subname"
5780                cat $pp_wrkdir/%pre.$cmp
5781                echo :   # causes script to exit true
5782            fi
5783
5784            if test -s $pp_wrkdir/%post.$cmp; then
5785                echo ""
5786                echo "%post $_subname"
5787                cat $pp_wrkdir/%post.$cmp
5788                echo :   # causes script to exit true
5789            fi
5790
5791            if test -s $pp_wrkdir/%preun.$cmp; then
5792                echo ""
5793                echo "%preun $_subname"
5794                cat $pp_wrkdir/%preun.$cmp
5795                echo :   # causes script to exit true
5796            fi
5797
5798            if test -s $pp_wrkdir/%postun.$cmp; then
5799                echo ""
5800                echo "%postun $_subname"
5801                cat $pp_wrkdir/%postun.$cmp
5802                echo :   # causes script to exit true
5803            fi
5804	done >>$specfile
5805
5806        #-- create a suitable work area for rpmbuild
5807	cat <<-. >$pp_wrkdir/.rpmmacros
5808		%_topdir $pp_wrkdir
5809		# XXX Note escaped %% for use in headerSprintf
5810		%_rpmfilename   %%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
5811	.
5812	mkdir $pp_wrkdir/RPMS
5813	mkdir $pp_wrkdir/BUILD
5814
5815	if test x"$pp_rpm_arch" = x"auto"; then
5816	    #-- Reduce the arch_seen list to exactly one item
5817	    case "$pp_rpm_arch_seen" in
5818		"i386 x86_64"|"x86_64 i386")
5819		    pp_rpm_arch_seen=x86_64;;
5820		*"s390 s390x"* | *"s390x s390"* )
5821		    pp_rpm_arch_seen=s390x;;
5822		*" "*)
5823		    pp_error "detected multiple targets: $pp_rpm_arch_seen"
5824		    pp_rpm_arch_seen=unknown;;	    # not detected
5825		"")
5826		    pp_warn "detected no binaries: using target noarch"
5827		    pp_rpm_arch_seen=noarch;;
5828		*)
5829		    pp_debug "detected architecture $pp_rpm_arch_seen"
5830	    esac
5831	    pp_rpm_arch="$pp_rpm_arch_seen"
5832	fi
5833
5834        . $pp_wrkdir/%fixup
5835
5836$pp_opt_debug && cat $specfile
5837
5838        pp_debug "creating: `pp_backend_rpm_names`"
5839
5840pp_debug "pp_rpm_arch_seen = <${pp_rpm_arch_seen}>"
5841pp_debug "pp_rpm_arch = <${pp_rpm_arch}>"
5842
5843	HOME=$pp_wrkdir \
5844	pp_verbose \
5845        $pp_rpm_rpmbuild -bb \
5846		--buildroot="$pp_destdir/" \
5847                --target="${pp_rpm_arch}" \
5848                --define='_unpackaged_files_terminate_build 0' \
5849                --define='_use_internal_dependency_generator 0' \
5850                `$pp_opt_debug && echo --verbose || echo --quiet` \
5851                $pp_rpm_rpmbuild_extra_flags \
5852		$specfile ||
5853            pp_error "Problem creating RPM packages"
5854
5855	for f in `pp_backend_rpm_names`; do
5856	    # The package might be in an arch-specific subdir
5857	    pkgfile=not-found
5858	    for dir in $pp_wrkdir/RPMS/${pp_rpm_arch} $pp_wrkdir/RPMS; do
5859		if test -f $dir/$f; then
5860		    pkgfile=$dir/$f
5861		fi
5862	    done
5863	    if test x"$pkgfile" = x"not-found"; then
5864                pp_error "Problem predicting RPM filename: $f"
5865	    else
5866		ln $pkgfile $pp_wrkdir/$f
5867	    fi
5868	done
5869}
5870
5871pp_rpm_output_name () {
5872    echo "${pp_rpm_name:-$name}`pp_rpm_subname "$1" -`-${pp_rpm_version:-$version}-${pp_rpm_release:-1}.${pp_rpm_arch}.rpm"
5873}
5874
5875pp_backend_rpm_names () {
5876    local cmp _subname
5877    for cmp in $pp_components; do
5878	pp_rpm_output_name $cmp
5879    done
5880}
5881
5882pp_backend_rpm_cleanup () {
5883    :
5884}
5885
5886pp_rpm_print_requires () {
5887    local _subname _name
5888
5889    echo "CPU:$pp_rpm_arch"
5890    ## XXX should be lines of the form (from file/ldd/objdump)
5891    #    EXEC:/bin/sh
5892    #    RTLD:libc.so.4:open
5893    rpm -q --requires -p $pp_wrkdir/`pp_rpm_output_name $1` |sed -e '/^rpmlib(/d;s/ //g;s/^/RPM:/' | sort -u
5894}
5895
5896pp_backend_rpm_install_script () {
5897    local cmp _subname
5898
5899    echo "#!/bin/sh"
5900    pp_install_script_common
5901
5902    cat <<.
5903
5904        cmp_to_pkgname () {
5905	    local oi name
5906	    if test x"\$1" = x"--only-installed"; then
5907		#-- only print if installation detected
5908		oi=false
5909		shift
5910	    else
5911		oi=true
5912	    fi
5913            test x"\$*" = x"all" &&
5914                set -- $pp_components
5915            for cmp
5916            do
5917                case \$cmp in
5918.
5919    for cmp in $pp_components; do
5920        _subname=`pp_rpm_subname $cmp -`
5921         echo "$cmp) name=${pp_rpm_name:-$name}${_subname};;"
5922    done
5923    cat <<.
5924                *) usage;;
5925                esac
5926		if \$oi || rpm -q "\$name" >/dev/null 2>/dev/null; then
5927		    echo "\$name"
5928		fi
5929            done
5930        }
5931
5932
5933        cmp_to_pathname () {
5934            test x"\$*" = x"all" &&
5935                set -- $pp_components
5936            for cmp
5937            do
5938                case \$cmp in
5939.
5940    for cmp in $pp_components; do
5941        echo "$cmp) echo \${PP_PKGDESTDIR:-.}/`pp_rpm_output_name $cmp` ;;"
5942    done
5943    cat <<.
5944                *) usage;;
5945                esac
5946            done
5947        }
5948
5949	print_requires () {
5950            test x"\$*" = x"all" &&
5951                set -- $pp_components
5952            for cmp
5953            do
5954                case \$cmp in
5955.
5956    for cmp in $pp_components; do
5957        echo "$cmp) cat <<'._end'"
5958	pp_rpm_print_requires $cmp
5959        echo "._end"; echo ';;'
5960    done
5961    cat <<.
5962                *) usage;;
5963                esac
5964            done
5965        }
5966
5967        test \$# -eq 0 && usage
5968        op="\$1"; shift
5969        case "\$op" in
5970            list-components)
5971                test \$# -eq 0 || usage \$op
5972                echo $pp_components
5973                ;;
5974            list-services)
5975                test \$# -eq 0 || usage \$op
5976                echo $pp_services
5977                ;;
5978            list-files)
5979                test \$# -ge 1 || usage \$op
5980                cmp_to_pathname "\$@"
5981                ;;
5982            install)
5983                test \$# -ge 1 || usage \$op
5984                verbose rpm -U --replacepkgs --oldpackage \
5985                    \`cmp_to_pathname "\$@"\`
5986                ;;
5987            uninstall)
5988                test \$# -ge 1 || usage \$op
5989                pkgs=\`cmp_to_pkgname --only-installed "\$@"\`
5990                if test -z "\$pkgs"; then
5991                    verbosemsg "nothing to uninstall"
5992                else
5993                    verbose rpm -e \$pkgs
5994                fi
5995                ;;
5996            start|stop)
5997                test \$# -ge 1 || usage \$op
5998                ec=0
5999                for svc
6000                do
6001                    verbose /etc/init.d/\$svc \$op || ec=1
6002                done
6003                exit \$ec
6004                ;;
6005            print-platform)
6006                test \$# -eq 0 || usage \$op
6007		echo "linux-${pp_rpm_arch}"
6008		;;
6009            print-requires)
6010                test \$# -ge 1 || usage \$op
6011                print_requires "\$@"
6012		;;
6013            *)
6014                usage
6015                ;;
6016        esac
6017.
6018
6019}
6020
6021pp_backend_rpm_probe () {
6022        echo "${pp_rpm_distro}-${pp_rpm_arch_std}"
6023}
6024
6025pp_backend_rpm_vas_platforms () {
6026    case "$pp_rpm_arch_std" in
6027	x86_64)	echo "linux-x86_64.rpm linux-x86.rpm";;
6028	*86)	echo "linux-x86.rpm";;
6029	s390)	echo "linux-s390";;
6030	s390x)	echo "linux-s390x";;
6031	ppc*)	echo "linux-glibc23-ppc64 linux-glibc22-ppc64";;
6032	ia64)	echo "linux-ia64";;
6033	*)	pp_die "unknown architecture $pp_rpm_arch_std";;
6034    esac
6035}
6036
6037pp_rpm_service_install_common () {
6038    cat <<-'.'
6039
6040        _pp_install_service () {
6041            local svc level
6042            svc="$1"
6043            if [ -x /usr/lib/lsb/install_initd -a ! -r /etc/redhat-release ]
6044            then
6045                # LSB-style install
6046                /usr/lib/lsb/install_initd /etc/init.d/$svc &> /dev/null
6047            elif [ -x /sbin/chkconfig ]; then
6048                # Red Hat/chkconfig-style install
6049                /sbin/chkconfig --add $svc &> /dev/null
6050                /sbin/chkconfig $svc off &> /dev/null
6051            else
6052		: # manual links under /etc/init.d
6053            fi
6054        }
6055
6056        _pp_enable_service () {
6057            local svc level
6058            svc="$1"
6059            if [ -x /usr/lib/lsb/install_initd -a ! -r /etc/redhat-release ]
6060            then
6061                # LSB-style install
6062		: # not sure how to enable
6063            elif [ -x /sbin/chkconfig ]; then
6064                # Red Hat/chkconfig-style install
6065                /sbin/chkconfig $svc on &> /dev/null
6066            else
6067                # manual install
6068                set -- `sed -n -e 's/^# Default-Start://p' /etc/init.d/$svc`
6069                start_priority=`sed -n -e 's/^# X-Quest-Start-Priority:[[:space:]]*//p' /etc/init.d/$svc`
6070                stop_priority=`sed -n -e 's/^# X-Quest-Stop-Priority:[[:space:]]*//p' /etc/init.d/$svc`
6071
6072                # Provide default start & stop priorities of 20 & 80 in
6073                # accordance with Debian update-rc.d defaults
6074                if [ -z "$start_priority" ]; then
6075                    start_priority=20
6076                fi
6077                if [ -z "$stop_priority" ]; then
6078                    stop_priority=80
6079                fi
6080                    
6081                if [ -d "/etc/rc.d" ];then
6082                    rcdir=/etc/rc.d
6083                else
6084                    rcdir=/etc
6085                fi
6086
6087                for level
6088                do ln -sf /etc/init.d/$svc $rcdir/rc$level.d/S$start_priority$svc; done
6089                set -- `sed -n -e 's/^# Default-Stop://p' /etc/init.d/$svc`
6090                for level
6091                do ln -sf /etc/init.d/$svc $rcdir/rc$level.d/K$stop_priority$svc; done
6092            fi
6093        }
6094.
6095}
6096
6097pp_rpm_service_remove_common () {
6098    cat <<-'.'
6099
6100        _pp_remove_service () {
6101            local svc
6102            svc="$1"
6103            /etc/init.d/$svc stop >/dev/null 2>&1
6104            if [ -x /usr/lib/lsb/remove_initd -a ! -r /etc/redhat-release ]
6105            then
6106                /usr/lib/lsb/remove_initd /etc/init.d/$svc &> /dev/null
6107            elif [ -x /sbin/chkconfig ]; then
6108                /sbin/chkconfig --del $svc &> /dev/null
6109            else
6110                if [ -d "/etc/rc.d" ];then
6111                    rcdir=/etc/rc.d
6112                else
6113                    rcdir=/etc
6114                fi
6115
6116                rm -f $rcdir/rc?.d/[SK]??$svc
6117            fi
6118        }
6119.
6120}
6121
6122
6123pp_rpm_service_install () {
6124    pp_rpm_service_make_init_script $1 >/dev/null ||
6125        pp_error "could not create init script for service $1"
6126    echo "_pp_install_service $1"
6127    test $enable = yes && echo "_pp_enable_service $1"
6128}
6129
6130pp_rpm_service_remove () {
6131    cat <<-.
6132        if [ "\$1" = "remove" -o "\$1" = "0" ]; then
6133            # only remove the service if not upgrade
6134            _pp_remove_service $1
6135        fi
6136.
6137}
6138
6139
6140pp_backend_rpm_init_svc_vars () {
6141
6142    reload_signal=
6143    start_runlevels=${pp_rpm_default_start_runlevels-"2 3 4 5"} # == lsb default-start
6144    stop_runlevels=${pp_rpm_default_stop_runlevels-"0 1 6"} # == lsb default-stop
6145    svc_description="${pp_rpm_default_svc_description}" # == lsb short descr
6146    svc_process=
6147
6148    lsb_required_start='$local_fs $network'
6149    lsb_should_start=
6150    lsb_required_stop=
6151    lsb_description=
6152
6153    start_priority=50
6154    stop_priority=50            #-- stop_priority = 100 - start_priority
6155}
6156
6157pp_rpm_service_group_make_init_script () {
6158    local grp=$1
6159    local svcs="$2"
6160    local script=/etc/init.d/$grp
6161    local out=$pp_destdir$script
6162
6163    pp_add_file_if_missing $script run 755 || return 0
6164
6165    cat <<-. >>$out
6166	#!/bin/sh
6167	svcs="$svcs"
6168.
6169
6170    cat <<-'.' >>$out
6171
6172        #-- prints usage message
6173        pp_usage () {
6174            echo "usage: $0 {start|stop|status|restart|reload|condrestart|try-restart|force-reload}" >&2
6175            return 2
6176        }
6177
6178        #-- starts services in order.. stops them all if any break
6179        pp_start () {
6180            undo=
6181            for svc in $svcs; do
6182                if /etc/init.d/$svc start; then
6183                    undo="$svc $undo"
6184                else
6185                    if test -n "$undo"; then
6186                        for svc in $undo; do
6187                           /etc/init.d/$svc stop
6188                        done
6189                        return 1
6190                    fi
6191                fi
6192            done
6193            return 0
6194        }
6195
6196        #-- stops services in reverse
6197        pp_stop () {
6198            reverse=
6199            for svc in $svcs; do
6200                reverse="$svc $reverse"
6201            done
6202            rc=0
6203            for svc in $reverse; do
6204                /etc/init.d/$svc stop || rc=$?
6205            done
6206            return $rc
6207        }
6208
6209        #-- returns true only if all services return true status
6210        pp_status () {
6211            rc=0
6212            for svc in $svcs; do
6213                /etc/init.d/$svc status || rc=$?
6214            done
6215            return $rc
6216        }
6217
6218        pp_reload () {
6219            rc=0
6220            for svc in $svcs; do
6221                /etc/init.d/$svc reload || rc=$?
6222            done
6223            return $rc
6224        }
6225
6226        case "$1" in
6227            start)          pp_start;;
6228            stop)           pp_stop;;
6229            restart)        pp_stop; pp_start;;
6230            status)         pp_status;;
6231            try-restart|condrestart)
6232                            if pp_status >/dev/null; then
6233                                    pp_restart
6234                            fi;;
6235            reload)         pp_reload;;
6236            force-reload)   if pp_status >/dev/null; then
6237                                    pp_reload
6238                            else
6239                                    pp_restart
6240                            fi;;
6241            *)              pp_usage;;
6242        esac
6243.
6244    chmod 755 $out
6245}
6246
6247pp_rpm_service_make_init_script () {
6248    local svc=$1
6249    local script=/etc/init.d/$svc
6250    local out=$pp_destdir$script
6251    local _process _cmd _rpmlevels
6252
6253    pp_add_file_if_missing $script run 755 || return 0
6254
6255    #-- start out as an empty shell script
6256    cat <<-'.' >$out
6257	#!/bin/sh
6258.
6259
6260    #-- determine the process name from $cmd unless $svc_process is given
6261    set -- $cmd
6262    _process=${svc_process:-"$1"}
6263
6264    #-- construct a start command that builds a pid file if needed
6265    _cmd="$cmd";
6266    if test -z "$pidfile"; then
6267        pidfile=/var/run/$svc.pid
6268        _cmd="$cmd & echo \$! > \$pidfile"
6269    fi
6270    if test "$user" != "root"; then
6271        _cmd="su $user -c exec $_cmd";
6272    fi
6273
6274    #-- generate the Red Hat chkconfig headers
6275    _rpmlevels=`echo $start_runlevels | tr -d ' '`
6276    cat <<-. >>$out
6277	# chkconfig: ${_rpmlevels:--} ${start_priority:-50} ${stop_priority:-50}
6278	# description: ${svc_description:-no description}
6279	# processname: ${_process}
6280	# pidfile: ${pidfile}
6281.
6282
6283    #-- generate the LSB init info
6284    cat <<-. >>$out
6285	### BEGIN INIT INFO
6286	# Provides: ${svc}
6287	# Required-Start: ${lsb_required_start}
6288	# Should-Start: ${lsb_should_start}
6289	# Required-Stop: ${lsb_required_stop}
6290	# Default-Start: ${start_runlevels}
6291	# Default-Stop: ${stop_runlevels}
6292	# Short-Description: ${svc_description}
6293	### END INIT INFO
6294	# Generated by PolyPackage ${pp_version}
6295	# ${copyright}
6296
6297.
6298
6299    if test x"${svc_description}" = x"${pp_rpm_default_svc_description}"; then
6300        svc_description=
6301    fi
6302
6303    #-- write service-specific definitions
6304    cat <<. >>$out
6305	#-- definitions specific to service ${svc}
6306	svc_name="${svc_description:-$svc service}"
6307	user="${user}"
6308	pidfile="${pidfile}"
6309	stop_signal="${stop_signal}"
6310	reload_signal="${reload_signal}"
6311	pp_exec_cmd () { $_cmd; }
6312.
6313
6314    #-- write the generic part of the init script
6315    cat <<'.' >>$out
6316
6317        #-- use system message logging, if available
6318        if [ -f /lib/lsb/init-functions -a ! -r /etc/redhat-release ]; then
6319            . /lib/lsb/init-functions
6320            pp_success_msg () { log_success_msg "$@"; }
6321            pp_failure_msg () { log_failure_msg "$@"; }
6322            pp_warning_msg () { log_warning_msg "$@"; }
6323        elif [ -f /etc/init.d/functions ]; then
6324            . /etc/init.d/functions
6325            pp_success_msg () { echo -n "$*"; success "$@"; echo; }
6326            pp_failure_msg () { echo -n "$*"; failure "$@"; echo; }
6327            pp_warning_msg () { echo -n "$*"; warning "$@"; echo; }
6328        else
6329            pp_success_msg () { echo ${1:+"$*:"} OK; }
6330            pp_failure_msg () { echo ${1:+"$*:"} FAIL; }
6331            pp_warning_msg () { echo ${1:+"$*:"} WARNING; }
6332        fi
6333
6334        #-- prints a status message
6335        pp_msg () { echo -n "$*: "; }
6336
6337        #-- prints usage message
6338        pp_usage () {
6339            echo "usage: $0 {start|stop|status|restart|reload|condrestart|try-restart|force-reload}" >&2
6340            return 2
6341        }
6342
6343        #-- reloads the service, if possible
6344        #   returns 0=success 1=failure 3=unimplemented
6345        pp_reload () {
6346            test -n "$reload_signal" || return 3 # unimplemented
6347            pp_msg "Reloading ${svc_name}"
6348            if pp_signal -${reload_signal}; then
6349                pp_success_msg
6350                return 0
6351            else
6352                pp_failure_msg "not running"
6353                return 1
6354            fi
6355        }
6356
6357        #-- delivers signal $1 to the pidfile
6358        #   returns 0=success 1=failure
6359        pp_signal () {
6360            if test -r "$pidfile"; then
6361                read pid < $pidfile
6362                kill "$@" "$pid" 2>/dev/null
6363            else
6364                return 1
6365            fi
6366        }
6367
6368        #-- prints information about the service status
6369        #   returns 0=running 1=crashed 3=stopped
6370        pp_status () {
6371            pp_msg "Checking for ${svc_name}"
6372            if pp_signal -0; then
6373                pp_success_msg "running"
6374                return 0
6375            elif test -r "$pidfile"; then
6376                pp_failure_msg "not running (crashed)"
6377                return 1
6378            else
6379                pp_failure_msg "not running"
6380                return 3
6381            fi
6382        }
6383
6384        #-- starts the service
6385        #   returns 0=success 1=failure
6386        pp_start () {
6387            pp_msg "Starting ${svc_name}"
6388            if pp_status >/dev/null; then
6389                pp_warning_msg "already started"
6390                return 0
6391            elif pp_exec_cmd; then
6392                pp_success_msg
6393                return 0
6394            else
6395                pp_failure_msg "cannot start"
6396                return 1
6397            fi
6398        }
6399
6400        #-- stops the service
6401        #   returns 0=success (always)
6402        pp_stop () {
6403            pp_msg "Stopping ${svc_name}"
6404            if pp_signal -${stop_signal}; then
6405                pp_success_msg
6406            else
6407                pp_success_msg "already stopped"
6408            fi
6409            rm -f "$pidfile"
6410            return 0
6411        }
6412
6413        #-- stops and starts the service
6414        pp_restart () {
6415            pp_stop
6416            pp_start
6417        }
6418
6419        case "$1" in
6420            start)          pp_start;;
6421            stop)           pp_stop;;
6422            restart)        pp_restart;;
6423            status)         pp_status;;
6424            try-restart|condrestart)
6425                            if pp_status >/dev/null; then
6426                                    pp_restart
6427                            fi;;
6428            reload)         pp_reload;;
6429            force-reload)   if pp_status >/dev/null; then
6430                                    pp_reload
6431                            else
6432                                    pp_restart
6433                            fi;;
6434            *)              pp_usage;;
6435        esac
6436
6437.
6438    chmod 755 $out
6439}
6440pp_backend_rpm_function () {
6441    case "$1" in
6442        pp_mkgroup) cat<<'.';;
6443            /usr/sbin/groupadd -f -r "$1"
6444.
6445        pp_mkuser:depends) echo pp_mkgroup;;
6446        pp_mkuser) cat<<'.';;
6447            pp_mkgroup "${2:-$1}" || return 1
6448            /usr/sbin/useradd \
6449		-g "${2:-$1}" \
6450		-M -d "${3:-/nonexistent}" \
6451		-s "${4:-/bin/false}" \
6452		-r "$1"
6453.
6454        pp_havelib) cat<<'.';;
6455            for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
6456                test -r "$pp_tmp_dir/lib$1.so{$2:+.$2}" && return 0
6457            done
6458            return 1
6459.
6460	*) false;;
6461    esac
6462}
6463
6464: NOTES <<.
6465
6466 # creating a dmg file for publishing on the web
6467    hdiutil create -srcfolder /path/foo foo.dmg
6468    hdiutil internet-enable -yes /path/foo.dmg
6469 # Layout for packages
6470    <name>-<cpy>/component/<file>
6471    <name>-<cpt>/extras/postinstall
6472    <name>-<cpt>/extras/postupgrade
6473 # /Developer/usr/bin/packagemaker (man packagemaker)
6474
6475    Make a bunch of packages, and then build a 'distribution'
6476    which is only understood by macos>10.4
6477
6478 # Message files in the resource path used are
6479    Welcome.{rtf,html,rtfd,txt} - limited text shown in Intro
6480    ReadMe.{rtf,html,rtfd,txt} - scrollable/printable, after Intro
6481    License.{rtf,html,rtfd,txt} - ditto, user must click 'Accept'
6482    background.{jpg,tif,gif,pict,eps,pdf} 620x418 background image
6483
6484 # These scripts looked for in the resource path
6485    InstallationCheck $pkgpath $defaultloc $targetvol
6486	0:ok 32:warn 32+x:warn[1] 64:stop 96+x:stop[2]
6487    VolumeCheck $volpath
6488	0:ok 32:failure 32+x:failure[3]
6489    preflight   $pkgpath $targetloc $targetvol    [priv]
6490    preinstall  $pkgpath $targetloc $targetvol    [priv]
6491    preupgrade  $pkgpath $targetloc $targetvol    [priv]
6492    postinstall $pkgpath $targetloc $targetvol    [priv]
6493    postupgrade $pkgpath $targetloc $targetvol    [priv]
6494    postflight  $pkgpath $targetloc $targetvol    [priv]
6495	0:ok else fail (for all scripts)
6496
6497    A detailed reason is deduced by finding an index x (16..31)
6498    in the file InstallationCheck.strings or VolumeCheck.strings.
6499
6500    Scripts marked [priv] are executed with root privileges.
6501    None of the [priv] scripts are used by metapackages.
6502
6503 # Default permissions
6504    Permissions of existing directories should match those
6505    of a clean install of the OS; typically root:admin 0775
6506    New directories or files should be 0775 or 0664 with the
6507    appropriate user:group.
6508    Exceptions:
6509	/etc	root:admin 0755
6510	/var    root:admin 0755
6511
6512    <http://developer.apple.com/documentation/DeveloperTools/Conceptual/SoftwareDistribution4/Concepts/sd_pkg_flags.html>
6513    Info.plist = {
6514     CFBundleGetInfoString: "1.2.3, Quest Software, Inc.",
6515     CFBundleIdentifier: "com.quest.rc.openssh",
6516     CFBundleShortVersionString: "1.2.3",
6517     IFMajorVersion: 1,
6518     IFMinorVersion: 2,
6519     IFPkgFlagAllowBackRev: false,
6520     IFPkgFlagAuthorizationAction: "AdminAuthorization",
6521     IFPkgFlagDefaultLocation: "/",
6522     IFPkgFlagFollowLinks: true,
6523     IFPkgFlagInstallFat: false,
6524     IFPkgFlagInstalledSize: <integer>,	    # this is added by packagemaker
6525     IFPkgFlagIsRequired: false,
6526     IFPkgFlagOverwritePermissions: false,
6527     IFPkgFlagRelocatable: false,
6528     IFPkgFlagRestartAction: "NoRestart",
6529     IFPkgFlagRootVolumeOnly: false,
6530     IFPkgFlagUpdateInstalledLanguages: false,
6531     IFPkgFormatVersion= 0.10000000149011612,
6532     IFRequirementDicts: [ {
6533       Level = "requires",
6534       SpecArgument = "/opt/quest/lib/libvas.4.2.0.dylib",
6535       SpecType = "file",
6536       TestObject = true,
6537       TestOperator = "eq", } ]
6538    }
6539
6540    Description.plist = {
6541     IFPkgDescriptionDescription = "this is the description text",
6542     IFPkgDescriptionTitle = "quest-openssh"
6543    }
6544
6545 # Startup scripts
6546    'launchd' is a kind of combined inetd and rc/init.d system.
6547    <http://developer.apple.com/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/DesigningDaemons.html>
6548    Create a /Library/LaunchDaemons/$daemonname.plist file
6549    Examples found in /System/Library/LaunchDaemons/
6550    See manual page launchd.plist(5) for details:
6551
6552    { Label: "com.quest.rc.foo",                        # required
6553      Program: "/sbin/program",
6554      ProgramArguments: [ "/sbin/program", "arg1", "arg2" ], # required
6555      RunAtLoad: true,
6556      WatchPaths: [ "/etc/crontab" ],
6557      QueueDirectories: [ "/var/cron/tabs" ],
6558      inetdCompatibility: { Wait: false },                   # inetd-only
6559      OnDemand: false,                                       # recommended
6560      SessionCreate: true,
6561      UserName: "nobody",
6562      InitGroups: true,
6563      Sockets: {                                             # inetd only
6564	Listeners: {
6565	   SockServiceName: "ssh",
6566	   Bonjour: ["ssh", "sftp-ssh"], } },
6567      Disabled: false,
6568      StandardErrorPath: "/dev/null",
6569    }
6570
6571
6572    How to add a new user
6573	dscl . -create /Users/$user
6574	dscl . -create /Users/$user UserShell /bin/bash
6575	dscl . -create /Users/$user RealName "$user"
6576	dscl . -create /Users/$user UniqueID $uid
6577	dscl . -create /Users/$user PrimaryGroupID $gid
6578	dscl . -create /Users/$user NFSHomeDirectory /Users/$user
6579	dscl . -passwd /Users/$user "$passwd"
6580	mkdir /Users/$user
6581	chown $uid.$gid /Users/$user
6582
6583.
6584
6585
6586pp_platforms="$pp_platforms macos"
6587
6588pp_backend_macos_detect () {
6589    [ x"$1" = x"Darwin" ]
6590}
6591
6592pp_backend_macos_init () {
6593    pp_macos_default_bundle_id_prefix="com.quest.rc."
6594    pp_macos_bundle_id=
6595    pp_macos_bundle_vendor=
6596    pp_macos_bundle_version=
6597    pp_macos_bundle_info_string=
6598    pp_macos_pkg_type=bundle
6599    pp_macos_pkg_license=
6600    pp_macos_pkg_readme=
6601    pp_macos_pkg_welcome=
6602    pp_macos_sudo=sudo
6603    pp_macos_installer_plugin=
6604    # OS X puts the library version *before* the .dylib extension
6605    pp_shlib_suffix='*.dylib'
6606}
6607
6608pp_macos_plist () {
6609    typeset in
6610    in=""
6611    while test $# -gt 0; do
6612     case "$1" in
6613
6614      start-plist) cat <<-.; in="  "; shift ;;
6615	<?xml version="1.0" encoding="UTF-8"?>
6616	<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
6617	<plist version="1.0">
6618.
6619      end-plist) echo "</plist>"; in=; shift;;
6620
6621      '[')   echo "$in<array>"; in="$in  "; shift;;
6622      ']')   echo "$in</array>"; in="${in#  }"; shift;;
6623      '{')   echo "<dict>"; in="$in      "; shift;;
6624      '}')   echo "</dict>"; in="${in#      }"; shift;;
6625      key)         shift; echo "$in<key>$1</key>"; shift;;
6626      string)      shift;
6627		   echo "$1" | sed -e 's/&/&amp;/g;s/</\&lt;/g;s/>/\&gt;/g;' \
6628				   -e 's/^/'"$in"'<string>/;s/$/<\/string>/';
6629		   shift;;
6630      true)        echo "$in<true/>"; shift;;
6631      false)       echo "$in<false/>"; shift;;
6632      real)        shift; echo "$in<real>$1</real>"; shift;;
6633      integer)     shift; echo "$in<integer>$1</integer>"; shift;;
6634      date)        shift; echo "$in<date>$1</date>"; shift;; # ISO 8601 format
6635      data)        shift; echo "$in<data>$1</data>"; shift;; # base64 encoded
6636      *)	   pp_error "pp_macos_plist: bad argument '$1'"; shift;;
6637     esac
6638    done
6639}
6640
6641pp_macos_rewrite_cpio () {
6642    typeset script
6643    script=$pp_wrkdir/cpio-rewrite.pl
6644    cat <<-'.' >$script
6645	#!/usr/bin/perl
6646	#
6647	# Filter a cpio file, applying the user/group/mode specified in %files
6648	#
6649	# A CPIO header block has octal fields at the following offset/lengths:
6650	#   0  6 magic
6651	#   6  6 dev
6652	#  12  6 ino
6653	#  18  6 mode
6654	#  24  6 uid
6655	#  30  6 gid
6656	#  36  6 nlink
6657	#  42  6 rdev
6658	#  48 11 mtime
6659	#  59  6 namesize (including NUL terminator)
6660	#  65 11 filesize
6661	#  76    --
6662	#
6663	use strict;
6664	use warnings;
6665	no strict 'subs';
6666
6667	# set %uid, %gid, %mode based on %files
6668	my (%uid, %gid, %mode, %users, %groups);
6669	my %type_map = ( d => 0040000, f => 0100000, s => 0120000 );
6670	while (<DATA>) {
6671	    my ($type,$mode,$uid,$gid,$flags,$name) =
6672	        m/^(.) (\S+) (\S+) (\S+) (\S+) (\S+)/;
6673	    $mode = $type eq "f" ? "0644" : "0755" if $mode eq "-";
6674	    $uid = 0 if $uid eq "-";
6675	    $gid = 0 if $gid eq "-";
6676	    if ($uid ne "=" and $uid =~ m/\D/) {
6677	        unless (exists $users{$uid}) {
6678	            my @pw = getpwnam($uid) or die "bad username '$uid'";
6679	            $users{$uid} = $pw[2];
6680	        }
6681	        $uid = $users{$uid};
6682	    }
6683	    if ($gid ne "=" and $gid =~ m/\D/) {
6684	        unless (exists $groups{$gid}) {
6685	            my @gr = getgrnam($gid) or die "bad group'$gid'";
6686	            $groups{$gid} = $gr[2];
6687	        }
6688	        $gid = $groups{$gid};
6689	    }
6690	    $name =~ s:/$:: if $type eq "d";
6691	    $name = ".".$name."\0";
6692	    $uid{$name} = sprintf("%06o",int($uid)) unless $uid eq "=";
6693	    $gid{$name} = sprintf("%06o",int($gid)) unless $gid eq "=";
6694	    $mode{$name} = sprintf("%06o",oct($mode)|$type_map{$type}) unless $mode eq "=";
6695	}
6696	undef %users;
6697	undef %groups;
6698	# parse the cpio file
6699	my $hdrlen = 76;
6700	while (read(STDIN, my $header, $hdrlen)) {
6701	    my ($name, $namesize, $filesize);
6702	    my $filepad = 0;
6703	    if ($header =~ m/^07070[12]/) {
6704	        # SVR4 ASCII format, convert to ODC
6705	        if ($hdrlen == 76) {
6706	            # Read in rest of header and update header len for SVR4
6707	            read(STDIN, $header, 110 - 76, 76);
6708	            $hdrlen = 110;
6709	        }
6710	        my $ino = hex(substr($header, 6, 8)) & 0x3ffff;
6711	        my $mode = hex(substr($header, 14, 8)) & 0x3ffff;
6712	        my $uid = hex(substr($header, 22, 8)) & 0x3ffff;
6713	        my $gid = hex(substr($header, 30, 8)) & 0x3ffff;
6714	        my $nlink = hex(substr($header, 38, 8)) & 0x3ffff;
6715	        my $mtime = hex(substr($header, 46, 8)) & 0xffffffff;
6716	        $filesize = hex(substr($header, 54, 8)) & 0xffffffff;
6717	        my $dev_maj = hex(substr($header, 62, 8));
6718	        my $dev_min = hex(substr($header, 70, 8));
6719	        my $dev = &makedev($dev_maj, $dev_min) & 0x3ffff;
6720	        my $rdev_maj = hex(substr($header, 78, 8));
6721	        my $rdev_min = hex(substr($header, 86, 8));
6722	        my $rdev = &makedev($rdev_maj, $rdev_min) & 0x3ffff;
6723	        $namesize = hex(substr($header, 94, 8)) & 0x3ffff;
6724	        read(STDIN, $name, $namesize);
6725	        # Header + name is padded to a multiple of 4 bytes
6726	        my $namepad = (($hdrlen + $namesize + 3) & 0xfffffffc) - ($hdrlen + $namesize);
6727	        read(STDIN, my $padding, $namepad) if ($namepad);
6728	        # File data is padded to be a multiple of 4 bytes
6729	        $filepad = (($filesize + 3) & 0xfffffffc) - $filesize;
6730
6731	        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);
6732	        $header = $new_header;
6733	    } elsif ($header =~ m/^070707/) {
6734	        # POSIX Portable ASCII Format
6735	        $namesize = oct(substr($header, 59, 6));
6736	        $filesize = oct(substr($header, 65, 11));
6737	        read(STDIN, $name, $namesize);
6738	    } else {
6739	        die "bad magic";
6740	    }
6741	    # update uid, gid and mode (already in octal)
6742	    substr($header, 24, 6) = $uid{$name} if exists $uid{$name};
6743	    substr($header, 30, 6) = $gid{$name} if exists $gid{$name};
6744	    substr($header, 18, 6) = $mode{$name} if exists $mode{$name};
6745	    print($header, $name);
6746	    # check for trailer at EOF
6747	    last if $filesize == 0 && $name =~ /^TRAILER!!!\0/;
6748	    # copy-through the file data
6749	    while ($filesize > 0) {
6750	        my $seg = 8192;
6751	        $seg = $filesize if $filesize < $seg;
6752	        read(STDIN, my $data, $seg);
6753	        print $data;
6754	        $filesize -= $seg;
6755	    }
6756	    # If file data is padded, skip it
6757	    read(STDIN, my $padding, $filepad) if ($filepad);
6758	}
6759	# pass through any padding at the end (blocksize-dependent)
6760	for (;;) {
6761	    my $numread = read(STDIN, my $data, 8192);
6762	    last unless $numread;
6763	    print $data;
6764	}
6765	exit(0);
6766
6767	sub makedev {
6768	    (((($_[0] & 0xff)) << 24) | ($_[1] & 0xffffff));
6769	}
6770	__DATA__
6771.
6772    # Append to the script the %files data
6773    cat "$@" </dev/null >> $script
6774    /usr/bin/perl $script || pp_error "pp_macos_rewrite_cpio error";
6775}
6776
6777pp_macos_files_bom () {
6778    typeset _l t m o g f p st owner
6779    while read t m o g f p st; do
6780	# make sure that $m is padded up to 4 digits long
6781	case "$m" in
6782	    ?) m="000$m";;
6783	    ??) m="00$m";;
6784	    ???) m="0$m";;
6785	    ?????*) pp_error "pp_macos_writebom: mode '$m' too long";;
6786	esac
6787
6788	# convert owner,group into owner/group in octal
6789	case $o in -)	o=0;; esac
6790	case $g in -)	g=0;; esac
6791	owner=`pp_d2o $o`/`pp_d2o $g`
6792
6793	case $t in
6794	    f)
6795		test x"$m" = x"000-" && m=0644
6796		echo ".$p	10$m	$owner	`
6797		    /usr/bin/cksum < "${pp_destdir}$p" |
6798		    awk '{print $2 "	" $1}'`"
6799		;;
6800	    d)
6801		test x"$m" = x"000-" && m=0755
6802		echo ".${p%/}	4$m	$owner"
6803		;;
6804	    s)
6805		test x"$m" = x"000-" && m=0755
6806		rl=`/usr/bin/readlink "${pp_destdir}$p"`
6807		#test x"$rl" = x"$st" ||
6808		#    pp_error "symlink mismatch $rl != $st"
6809		echo ".$p	12$m	$owner	`
6810		    /usr/bin/readlink -n "${pp_destdir}$p" |
6811		    /usr/bin/cksum |
6812		    awk '{print $2 "	" $1}'`	$st"
6813		;;
6814	esac
6815    done
6816}
6817
6818pp_macos_bom_fix_parents () {
6819    perl -pe '
6820	sub dirname { my $d=shift; $d=~s,/[^/]*$,,; $d; }
6821	sub chk { my $d=shift;
6822		  &chk(&dirname($d)) if $d =~ m,/,;
6823		  unless ($seen{$d}++) {
6824		    # Make sure we do not override system directories
6825		    if ($d =~ m:^\./(etc|var)$:) {
6826		      my $tgt = "private/$1";
6827		      my ($sum, $len) = split(/\s+/, `/usr/bin/printf "$tgt" | /usr/bin/cksum /dev/stdin`);
6828		      print "$d\t120755\t0/0\t$len\t$sum\t$tgt\n";
6829		    } elsif ($d eq "." || $d eq "./Library") {
6830		      print "$d\t41775\t0/80\n";
6831		    } elsif ($d eq "./Applications" || $d eq "./Developer") {
6832		      print "$d\t40775\t0/80\n";
6833		    } else {
6834		      print "$d\t40755\t0/0\n";
6835		    }
6836		  }
6837		}
6838	m/^(\S+)\s+(\d+)/;
6839	if (oct($2) & 040000) {
6840	    $seen{$1}++; # directory
6841	}
6842	&chk(&dirname($1));'
6843}
6844
6845pp_macos_files_size () {
6846    typeset _l t m o g f p st owner
6847    while read t m o g f p st; do
6848	case $t in
6849	    f)	wc -c < "${pp_destdir}$p";;
6850	    s)	echo 4095;;
6851	    d)	;; # always seems to be zero
6852	esac
6853    done | awk '{n+=1+int($1/4096)} END {print n*4}'
6854}
6855
6856pp_o2d () {
6857    awk 'BEGIN { x=0; '`echo "$1" |
6858	sed -e 's/./x=x*8+&;/g'`'print x;}' </dev/null
6859}
6860pp_d2o () {
6861    case "$1" in
6862	[0-7]) echo $1;;
6863	*) awk 'BEGIN { printf("%o\n", 0+('"$1"'));}' < /dev/null;;
6864    esac
6865}
6866
6867pp_macos_mkbom () {
6868    #/usr/bin/mkbom -i $1 $2
6869    typeset path mode ugid size cksum linkpath
6870    typeset bomstage
6871
6872    # Use mkbom if it understands -i (avoids a copy)
6873    if /usr/bin/mkbom -i /dev/null "$2" 2>/dev/null; then
6874	rm -f "$2"
6875	/usr/bin/mkbom -i "$1" "$2"
6876	return
6877    fi
6878
6879    # On 10.4 we have this nonsense.
6880    pp_warn "mkbom workaround: copying source files to staging area"
6881
6882    bomstage=$pp_wrkdir/bom_stage
6883    $pp_macos_sudo /bin/mkdir "$bomstage"
6884    while IFS='	' read path mode ugid size cksumi linkpath; do
6885	if test -h "$pp_destdir/$path"; then
6886	    $pp_macos_sudo /bin/ln -s "$linkpath" "$bomstage/$path"
6887	else
6888	    if test -d "$pp_destdir/$path"; then
6889		$pp_macos_sudo /bin/mkdir -p "$bomstage/$path"
6890	    else
6891		$pp_macos_sudo /bin/cp "$pp_destdir/$path" "$bomstage/$path"
6892	    fi
6893	    $pp_macos_sudo /bin/chmod $mode "$bomstage/$path"
6894	    $pp_macos_sudo /usr/sbin/chown `echo $ugid| tr / :` "$bomstage/$path"
6895	fi
6896    done <"$1"
6897    (cd $bomstage && $pp_macos_sudo mkbom . $pp_wrkdir/bom_stage.bom) ||
6898	pp_error "mkbom failed"
6899    $pp_macos_sudo mv $pp_wrkdir/bom_stage.bom "$2"
6900}
6901
6902pp_backend_macos () {
6903    : ${pp_macos_bundle_id:=$pp_macos_default_bundle_id_prefix$name}
6904    case "$pp_macos_pkg_type" in
6905	bundle) pp_backend_macos_bundle;;
6906	flat) pp_backend_macos_flat;;
6907	*) pp_error "unsupported package type $pp_macos_pkg_type";;
6908    esac
6909}
6910
6911pp_backend_macos_bundle () {
6912    typeset pkgdir Contents Resources lprojdir svc
6913    typeset Info_plist Description_plist
6914    typeset bundle_vendor bundle_version size cmp filelists
6915
6916    mac_version=`sw_vers -productVersion`
6917    bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
6918
6919    if test -z "$pp_macos_bundle_version"; then
6920        bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
6921            -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
6922    else
6923        bundle_version="$pp_macos_bundle_version"
6924    fi
6925    source_version=`echo $version | sed 's/.*\.//'`
6926
6927    # build the package layout
6928    pkgdir=$pp_wrkdir/$name.pkg
6929    Contents=$pkgdir/Contents
6930    Resources=$Contents/Resources
6931    lprojdir=$Resources/en.lproj
6932    mkdir $pkgdir $Contents $Resources $lprojdir ||
6933	pp_error "Can't make package temporary directories"
6934
6935    echo "major: 1" > $Resources/package_version
6936    echo "minor: 0" >> $Resources/package_version
6937    echo "pmkrpkg1" > $Contents/PkgInfo
6938    case $mac_version in
6939        "10.6"*)
6940            xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/package_version"
6941            xattr -w "com.apple.TextEncoding" "macintosh;0" "$Contents/PkgInfo"
6942            ;;
6943    esac
6944
6945    # Copy welcome file/dir for display at package install time.
6946    if test -n "$pp_macos_pkg_welcome"; then
6947	typeset sfx
6948	sfx=`echo "$pp_macos_pkg_welcome"|sed 's/^.*\.\([^\.]*\)$/\1/'`
6949	case "$sfx" in
6950	    rtf|html|rtfd|txt) ;;
6951	    *) sfx=txt;;
6952	esac
6953	cp -R ${pp_macos_pkg_welcome} $Resources/Welcome.$sfx
6954    fi
6955
6956    # Copy readme file/dir for display at package install time.
6957    if test -n "$pp_macos_pkg_readme"; then
6958	typeset sfx
6959	sfx=`echo "$pp_macos_pkg_readme"|sed 's/^.*\.\([^\.]*\)$/\1/'`
6960	case "$sfx" in
6961	    rtf|html|rtfd|txt) ;;
6962	    *) sfx=txt;;
6963	esac
6964	cp -R ${pp_macos_pkg_readme} $Resources/ReadMe.$sfx
6965    fi
6966
6967    # Copy license file/dir for display at package install time.
6968    if test -n "$pp_macos_pkg_license"; then
6969	typeset sfx
6970	sfx=`echo "$pp_macos_pkg_license"|sed 's/^.*\.\([^\.]*\)$/\1/'`
6971	case "$sfx" in
6972	    rtf|html|rtfd|txt) ;;
6973	    *) sfx=txt;;
6974	esac
6975	cp -R ${pp_macos_pkg_license} $Resources/License.$sfx
6976    fi
6977
6978    # Add services (may modify %files)
6979    for svc in $pp_services .; do
6980	test . = "$svc" && continue
6981	pp_macos_add_service $svc
6982    done
6983
6984    # Find file lists (%files.* includes ignore files)
6985    for cmp in $pp_components; do
6986	test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
6987    done
6988
6989    # compute the installed size
6990    size=`cat $filelists | pp_macos_files_size`
6991
6992    #-- Create Info.plist
6993    Info_plist=$Contents/Info.plist
6994    pp_macos_plist \
6995	start-plist \{ \
6996	key CFBundleGetInfoString string \
6997	    "${pp_macos_bundle_info_string:-$version $bundle_vendor}" \
6998	key CFBundleIdentifier string \
6999	    "${pp_macos_bundle_id}" \
7000    key CFBundleName string "$name" \
7001	key CFBundleShortVersionString string "$bundle_version" \
7002	key IFMajorVersion integer 1 \
7003	key IFMinorVersion integer 0 \
7004	key IFPkgFlagAllowBackRev false \
7005	key IFPkgFlagAuthorizationAction string "RootAuthorization" \
7006	key IFPkgFlagDefaultLocation string "/" \
7007	key IFPkgFlagFollowLinks true \
7008	key IFPkgFlagInstallFat true \
7009	key IFPkgFlagInstalledSize integer $size \
7010	key IFPkgFlagIsRequired false \
7011	key IFPkgFlagOverwritePermissions true \
7012	key IFPkgFlagRelocatable false \
7013	key IFPkgFlagRestartAction string "NoRestart" \
7014	key IFPkgFlagRootVolumeOnly true \
7015	key IFPkgFlagUpdateInstalledLanguages false \
7016	key IFPkgFlagUseUserMask false \
7017	key IFPkgFormatVersion real 0.10000000149011612 \
7018	key SourceVersion string $source_version \
7019	\} end-plist> $Info_plist
7020
7021    # write en.lproj/Description.plist
7022    Description_plist=$lprojdir/Description.plist
7023    pp_macos_plist \
7024 	start-plist \{ \
7025        key IFPkgDescriptionDeleteWarning string "" \
7026	    key IFPkgDescriptionDescription string "$pp_macos_bundle_info_string" \
7027	    key IFPkgDescriptionTitle       string "$name" \
7028	    key IFPkgDescriptionVersion string "$version" \
7029 	\} end-plist > $Description_plist
7030
7031    # write Resources/files
7032    awk '{print $6}' $filelists > $Resources/files
7033
7034    # write package size file
7035    printf \
7036"NumFiles 0
7037InstalledSize $size
7038CompressedSize 0
7039" > $Resources/$name.sizes
7040
7041    # write Resources/preinstall
7042    for cmp in $pp_components; do
7043	if test -s $pp_wrkdir/%pre.$cmp; then
7044	    if test ! -s $Resources/preinstall; then
7045		echo "#!/bin/sh" > $Resources/preinstall
7046		chmod +x $Resources/preinstall
7047	    fi
7048	    cat $pp_wrkdir/%pre.$cmp >> $Resources/preinstall
7049	    echo : >> $Resources/preinstall
7050	fi
7051    done
7052
7053    # write Resources/postinstall
7054    for cmp in $pp_components; do
7055	if test -s $pp_wrkdir/%post.$cmp; then
7056	    if test ! -s $Resources/postinstall; then
7057		echo "#!/bin/sh" > $Resources/postinstall
7058		chmod +x $Resources/postinstall
7059	    fi
7060	    cat $pp_wrkdir/%post.$cmp >> $Resources/postinstall
7061	    echo : >> $Resources/postinstall
7062	fi
7063    done
7064
7065    # write Resources/postupgrade
7066    for cmp in $pp_components; do
7067	if test -s $pp_wrkdir/%postup.$cmp; then
7068	    if test ! -s $Resources/postupgrade; then
7069		echo "#!/bin/sh" > $Resources/postupgrade
7070		chmod +x $Resources/postupgrade
7071	    fi
7072	    cat $pp_wrkdir/%postup.$cmp >> $Resources/postupgrade
7073	    echo : >> $Resources/postupgrade
7074	fi
7075    done
7076
7077    # write Resources/preremove
7078    for cmp in $pp_components; do
7079	if test -s $pp_wrkdir/%preun.$cmp; then
7080	    if test ! -s $Resources/preremove; then
7081		echo "#!/bin/sh" > $Resources/preremove
7082		chmod +x $Resources/preremove
7083	    fi
7084	    cat $pp_wrkdir/%preun.$cmp >> $Resources/preremove
7085	    echo : >> $Resources/preremove
7086	fi
7087    done
7088
7089    # write Resources/postremove
7090    for cmp in $pp_components; do
7091	if test -s $pp_wrkdir/%postun.$cmp; then
7092	    if test ! -s $Resources/postremove; then
7093		echo "#!/bin/sh" > $Resources/postremove
7094		chmod +x $Resources/postremove
7095	    fi
7096	    cat $pp_wrkdir/%postun.$cmp >> $Resources/postremove
7097	    echo : >> $Resources/postremove
7098	fi
7099    done
7100
7101    # write uninstall info
7102    echo "version=$version" > $Resources/uninstall
7103    if [ -n "$pp_macos_requires" ];then
7104        echo "requires=$pp_macos_requires" >> $Resources/uninstall
7105    fi
7106
7107    . $pp_wrkdir/%fixup
7108
7109    # Create the bill-of-materials (Archive.bom)
7110    cat $filelists | pp_macos_files_bom | sort |
7111	pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
7112
7113    pp_macos_mkbom $pp_wrkdir/tmp.bomls $Contents/Archive.bom
7114
7115    # Create the cpio archive (Archive.pax.gz)
7116    (
7117    cd $pp_destdir &&
7118    awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $Contents/Archive.pax.gz
7119    )
7120
7121    # Copy installer plugins if any
7122    if test -n "$pp_macos_installer_plugin"; then
7123	if test ! -f "$pp_macos_installer_plugin/InstallerSections.plist"; then
7124	    pp_error "Missing InstallerSections.plist file in $pp_macos_installer_plugin"
7125	fi
7126	mkdir -p $pkgdir/Plugins
7127	cp -R "$pp_macos_installer_plugin"/* $pkgdir/Plugins
7128    fi
7129
7130    test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
7131
7132    rm -f ${name}-${version}.dmg
7133    hdiutil create -fs HFS+ -srcfolder $pkgdir -volname $name ${name}-${version}.dmg
7134}
7135
7136pp_backend_macos_flat () {
7137    typeset pkgdir bundledir Resources lprojdir svc
7138    typeset Info_plist Description_plist
7139    typeset bundle_vendor bundle_version size numfiles cmp filelists
7140
7141    mac_version=`sw_vers -productVersion`
7142    bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
7143
7144    if test -z "$pp_macos_bundle_version"; then
7145        bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
7146            -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
7147    else
7148        bundle_version="$pp_macos_bundle_version"
7149    fi
7150    source_version=`echo $version | sed 's/.*\.//'`
7151
7152    # build the flat package layout
7153    pkgdir=$pp_wrkdir/pkg
7154    bundledir=$pp_wrkdir/pkg/$name.pkg
7155    Resources=$pkgdir/Resources
7156    lprojdir=$Resources/en.lproj
7157    mkdir $pkgdir $bundledir $Resources $lprojdir ||
7158	pp_error "Can't make package temporary directories"
7159
7160    # Add services (may modify %files)
7161    for svc in $pp_services .; do
7162	test . = "$svc" && continue
7163	pp_macos_add_service $svc
7164    done
7165
7166    # Find file lists (%files.* includes ignore files)
7167    for cmp in $pp_components; do
7168	test -f $pp_wrkdir/%files.$cmp && filelists="$filelists${filelists:+ }$pp_wrkdir/%files.$cmp"
7169    done
7170
7171    # compute the installed size and number of files/dirs
7172    size=`cat $filelists | pp_macos_files_size`
7173    numfiles=`cat $filelists | wc -l`
7174    numfiles="${numfiles##* }"
7175
7176    # Write Distribution file
7177    cat <<-. >$pkgdir/Distribution
7178	<?xml version="1.0" encoding="UTF-8"?>
7179	<installer-script minSpecVersion="1.000000" authoringTool="com.quest.rc.PolyPkg" authoringToolVersion="$pp_version" authoringToolBuild="$pp_revision">
7180	    <title>$name $version</title>
7181	    <options customize="never" allow-external-scripts="no"/>
7182	    <domains enable_localSystem="true"/>
7183.
7184    if test -n "$pp_macos_pkg_welcome"; then
7185	cp -R "${pp_macos_pkg_welcome}" $Resources
7186	echo "    <welcome file=\"${pp_macos_pkg_welcome##*/}\"/>" >>$pkgdir/Distribution
7187    fi
7188    if test -n "$pp_macos_pkg_readme"; then
7189	cp -R "${pp_macos_pkg_readme}" $Resources
7190	echo "    <readme file=\"${pp_macos_pkg_readme##*/}\"/>" >>$pkgdir/Distribution
7191    fi
7192    if test -n "$pp_macos_pkg_license"; then
7193	cp -R "${pp_macos_pkg_license}" $Resources
7194	echo "    <license file=\"${pp_macos_pkg_license##*/}\"/>" >>$pkgdir/Distribution
7195    fi
7196    cat <<-. >>$pkgdir/Distribution
7197	    <choices-outline>
7198	        <line choice="choice0"/>
7199	    </choices-outline>
7200	    <choice id="choice0" title="$name $version">
7201	        <pkg-ref id="${pp_macos_bundle_id}"/>
7202	    </choice>
7203	    <pkg-ref id="${pp_macos_bundle_id}" installKBytes="$size" version="$version" auth="Root">#$name.pkg</pkg-ref>
7204	</installer-script>
7205.
7206
7207    # write scripts archive
7208    # XXX - missing preupgrade, preflight, postflight
7209    mkdir $pp_wrkdir/scripts
7210    for cmp in $pp_components; do
7211	if test -s $pp_wrkdir/%pre.$cmp; then
7212	    if test ! -s $pp_wrkdir/scripts/preinstall; then
7213		echo "#!/bin/sh" > $pp_wrkdir/scripts/preinstall
7214		chmod +x $pp_wrkdir/scripts/preinstall
7215	    fi
7216	    cat $pp_wrkdir/%pre.$cmp >> $pp_wrkdir/scripts/preinstall
7217	    echo : >> $pp_wrkdir/scripts/preinstall
7218	fi
7219	if test -s $pp_wrkdir/%post.$cmp; then
7220	    if test ! -s $pp_wrkdir/scripts/postinstall; then
7221		echo "#!/bin/sh" > $pp_wrkdir/scripts/postinstall
7222		chmod +x $pp_wrkdir/scripts/postinstall
7223	    fi
7224	    cat $pp_wrkdir/%post.$cmp >> $pp_wrkdir/scripts/postinstall
7225	    echo : >> $pp_wrkdir/scripts/postinstall
7226	fi
7227	if test -s $pp_wrkdir/%postup.$cmp; then
7228	    if test ! -s $pp_wrkdir/scripts/postupgrade; then
7229		echo "#!/bin/sh" > $pp_wrkdir/scripts/postupgrade
7230		chmod +x $pp_wrkdir/scripts/postupgrade
7231	    fi
7232	    cat $pp_wrkdir/%postup.$cmp >> $pp_wrkdir/scripts/postupgrade
7233	    echo : >> $pp_wrkdir/scripts/postupgrade
7234	fi
7235	# XXX - not supported
7236	if test -s $pp_wrkdir/%preun.$cmp; then
7237	    if test ! -s $pp_wrkdir/scripts/preremove; then
7238		echo "#!/bin/sh" > $pp_wrkdir/scripts/preremove
7239		chmod +x $pp_wrkdir/scripts/preremove
7240	    fi
7241	    cat $pp_wrkdir/%preun.$cmp >> $pp_wrkdir/scripts/preremove
7242	    echo : >> $pp_wrkdir/scripts/preremove
7243	fi
7244	# XXX - not supported
7245	if test -s $pp_wrkdir/%postun.$cmp; then
7246	    if test ! -s $pp_wrkdir/scripts/postremove; then
7247		echo "#!/bin/sh" > $pp_wrkdir/scripts/postremove
7248		chmod +x $pp_wrkdir/scripts/postremove
7249	    fi
7250	    cat $pp_wrkdir/%postun.$cmp >> $pp_wrkdir/scripts/postremove
7251	    echo : >> $pp_wrkdir/scripts/postremove
7252	fi
7253    done
7254    if test "`echo $pp_wrkdir/scripts/*`" != "$pp_wrkdir/scripts/*"; then
7255	# write scripts archive, scripts are mode 0755 uid/gid 0/0
7256	# resetting the owner and mode is not strictly required
7257	(
7258	cd $pp_wrkdir/scripts || pp_error "Can't cd to $pp_wrkdir/scripts"
7259	rm -f $pp_wrkdir/tmp.files.scripts
7260	for s in *; do
7261	    echo "f 0755 0 0 - ./$s" >>$pp_wrkdir/tmp.files.scripts
7262	done
7263	find . -type f | /usr/bin/cpio -o | pp_macos_rewrite_cpio $pp_wrkdir/tmp.files.scripts | gzip -9f -c > $bundledir/Scripts
7264	)
7265    fi
7266
7267    # Write PackageInfo file
7268    cat <<-. >$bundledir/PackageInfo
7269	<?xml version="1.0" encoding="UTF-8"?>
7270	<pkg-info format-version="2" identifier="${pp_macos_bundle_id}" version="$version" install-location="/" relocatable="false" overwrite-permissions="true" followSymLinks="true" auth="root">
7271	    <payload installKBytes="$size" numberOfFiles="$numfiles"/>
7272.
7273    if test -s $bundledir/Scripts; then
7274	echo "    <scripts>" >>$bundledir/PackageInfo
7275	for s in preflight postflight preinstall postinstall preupgrade postupgrade; do
7276	    if test -s "$pp_wrkdir/scripts/$s"; then
7277		echo "	<$s file=\"$s\"/>" >>$bundledir/PackageInfo
7278	    fi
7279	done
7280	echo "    </scripts>" >>$bundledir/PackageInfo
7281    fi
7282    cat <<-. >>$bundledir/PackageInfo
7283	</pkg-info>
7284.
7285
7286    . $pp_wrkdir/%fixup
7287
7288    # Create the bill-of-materials (Bom)
7289    cat $filelists | pp_macos_files_bom | sort |
7290	pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
7291    pp_macos_mkbom $pp_wrkdir/tmp.bomls $bundledir/Bom
7292
7293    # Create the cpio payload
7294    (
7295    cd $pp_destdir || pp_error "Can't cd to $pp_destdir"
7296    awk '{ print "." $6 }' $filelists | sed 's:/$::' | sort | /usr/bin/cpio -o | pp_macos_rewrite_cpio $filelists | gzip -9f -c > $bundledir/Payload
7297    )
7298
7299    # Copy installer plugins if any
7300    if test -n "$pp_macos_installer_plugin"; then
7301	if test ! -f "$pp_macos_installer_plugin/InstallerSections.plist"; then
7302	    pp_error "Missing InstallerSections.plist file in $pp_macos_installer_plugin"
7303	fi
7304	mkdir -p $pkgdir/Plugins
7305	cp -R "$pp_macos_installer_plugin"/* $pkgdir/Plugins
7306    fi
7307
7308    test -d $pp_wrkdir/bom_stage && $pp_macos_sudo rm -rf $pp_wrkdir/bom_stage
7309
7310    # Create the flat package with xar (like pkgutil --flatten does)
7311    # Note that --distribution is only supported by Mac OS X 10.6 and above
7312    xar_flags="--compression=bzip2 --no-compress Scripts --no-compress Payload"
7313    case $mac_version in
7314        "10.5"*) ;;
7315	*)	 xar_flags="$xar_flags --distribution";;
7316    esac
7317    (cd $pkgdir && /usr/bin/xar $xar_flags -cf "../$name-$version.pkg" *)
7318}
7319
7320pp_backend_macos_cleanup () {
7321    :
7322}
7323
7324pp_backend_macos_names () {
7325    case "$pp_macos_pkg_type" in
7326	bundle) echo ${name}.pkg;;
7327	flat) echo ${name}-${version}.pkg;;
7328	*) pp_error "unsupported package type $pp_macos_pkg_type";;
7329    esac
7330}
7331
7332pp_backend_macos_install_script () {
7333    echo '#!/bin/sh'
7334    typeset pkgname platform
7335
7336    pkgname="`pp_backend_macos_names`"
7337    platform="`pp_backend_macos_probe`"
7338    pp_install_script_common
7339
7340    cat <<.
7341	test \$# -eq 0 && usage
7342	op="\$1"; shift
7343
7344	case "\$op" in
7345	list-components)
7346	    test \$# -eq 0 || usage \$op
7347	    echo "$pp_components"
7348	    ;;
7349	list-services)
7350	    test \$# -eq 0 || usage \$op
7351	    echo "$pp_services"
7352	    ;;
7353	list-files)
7354	    test \$# -ge 1 || usage \$op
7355	    echo \${PP_PKGDESTDIR:-.}/"$pkgname"
7356	    ;;
7357	install)
7358	    test \$# -ge 1 || usage \$op
7359	    vol=/Volumes/pp\$\$
7360	    pkg=\$vol/${name}-${version}.pkg
7361	    hdiutil attach -readonly -mountpoint \$vol \
7362		\${PP_PKGDESTDIR:-.}/"$pkgname"
7363	    trap "hdiutil detach \$vol" 0
7364	    installer -pkginfo -pkg \$pkg
7365	    installer -verbose -pkg \$pkg -target /
7366	    ;;
7367	uninstall)
7368	    test \$# -ge 1 || usage \$op
7369	    # XXX
7370	    echo "Uninstall not implemented" >&2
7371	    exit 1;;
7372	start|stop)
7373	    test \$# -ge 1 || usage \$op
7374	    ec=0
7375	    for svc
7376	    do
7377		# XXX
7378		echo "\${op} not implemented" >&2
7379		ec=1
7380	    done
7381	    exit \$ec
7382	    ;;
7383	print-platform)
7384	    echo "$platform"
7385	    ;;
7386	*)
7387	    usage;;
7388	esac
7389.
7390}
7391
7392pp_backend_macos_init_svc_vars () {
7393    pp_macos_start_services_after_install=false
7394    pp_macos_service_name=
7395    pp_macos_default_service_id_prefix="com.quest.rc."
7396    pp_macos_service_id=
7397    pp_macos_service_user=
7398    pp_macos_service_group=
7399    pp_macos_service_initgroups=
7400    pp_macos_service_umask=
7401    pp_macos_service_cwd=
7402    pp_macos_service_nice=
7403    pp_macos_svc_plist_file=
7404}
7405
7406pp_macos_launchd_plist () {
7407    typeset svc svc_id
7408
7409    svc="$1"
7410    svc_id="$2"
7411
7412    set -- $cmd
7413
7414    if [ -n "$pp_macos_svc_plist_file" ]; then
7415        echo "## Launchd plist file already defined at $pp_macos_svc_plist_file"
7416        return
7417    fi
7418
7419    echo "## Generating the launchd plist file for $svc"
7420    pp_macos_svc_plist_file="$pp_wrkdir/$svc.plist"
7421    cat <<-. > $pp_macos_svc_plist_file
7422	<?xml version="1.0" encoding="UTF-8"?>
7423	<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
7424	http://www.apple.com/DTDs/PropertyList-1.0.dtd >
7425	<plist version="1.0">
7426	<dict>
7427	    <key>Label</key>
7428	    <string>$svc_id</string>
7429	    <key>ProgramArguments</key>
7430	    <array>
7431.
7432    while test $# != 0; do
7433	printf "        <string>$1</string>\n" >> $pp_macos_svc_plist_file
7434	shift
7435    done
7436    cat <<-. >> $pp_macos_svc_plist_file
7437	    </array>
7438	    <key>KeepAlive</key>
7439	    <true/>
7440.
7441    if test -n "$pp_macos_service_user"; then
7442	printf "    <key>UserName</key>\n" >> $pp_macos_svc_plist_file
7443	printf "    <string>$pp_macos_service_user</string>\n" >> $pp_macos_svc_plist_file
7444    fi
7445    if test -n "$pp_macos_service_group"; then
7446	printf "    <key>GroupName</key>\n" >> $pp_macos_svc_plist_file
7447	printf "    <string>$pp_macos_service_group</string>\n" >> $pp_macos_svc_plist_file
7448    fi
7449    if test -n "$pp_macos_service_initgroups"; then
7450	printf "    <key>InitGroups</key>\n" >> $pp_macos_svc_plist_file
7451	printf "    <string>$pp_macos_service_initgroups</string>\n" >> $pp_macos_svc_plist_file
7452    fi
7453    if test -n "$pp_macos_service_umask"; then
7454	printf "    <key>Umask</key>\n" >> $pp_macos_svc_plist_file
7455	printf "    <string>$pp_macos_service_umask</string>\n" >> $pp_macos_svc_plist_file
7456    fi
7457    if test -n "$pp_macos_service_cwd"; then
7458	printf "    <key>WorkingDirectory</key>\n" >> $pp_macos_svc_plist_file
7459	printf "    <string>$pp_macos_service_cwd</string>\n" >> $pp_macos_svc_plist_file
7460    fi
7461    if test -n "$pp_macos_service_nice"; then
7462	printf "    <key>Nice</key>\n" >> $pp_macos_svc_plist_file
7463	printf "    <string>$pp_macos_service_nice</string>\n" >> $pp_macos_svc_plist_file
7464    fi
7465    cat <<-. >> $pp_macos_svc_plist_file
7466	</dict>
7467	</plist>
7468.
7469}
7470
7471pp_macos_add_service () {
7472    typeset svc svc_id plist_file plist_dir
7473
7474    pp_load_service_vars "$1"
7475    svc=${pp_macos_service_name:-$1}
7476    svc_id=${pp_macos_service_id:-$pp_macos_default_service_id_prefix$svc}
7477
7478    #-- create a plist file for svc
7479    pp_macos_launchd_plist "$svc" "$svc_id"
7480
7481    #-- copy the plist file into place and add to %files
7482    plist_dir="/Library/LaunchDaemons"
7483    plist_file="$plist_dir/$svc_id.plist"
7484    mkdir -p "$pp_destdir/$plist_dir"
7485    cp "$pp_macos_svc_plist_file" "$pp_destdir/$plist_file"
7486    pp_add_file_if_missing "$plist_file"
7487
7488    #-- add code to start the service on install
7489    ${pp_macos_start_services_after_install} && <<-. >> $pp_wrkdir/%post.$svc
7490	# start service '$svc' automatically after install
7491	launchctl load "$plist_file"
7492.
7493}
7494
7495pp_backend_macos_probe () {
7496    typeset name vers arch
7497    case `sw_vers -productName` in
7498         "Mac OS X") name="macos";;
7499	 *)          name="unknown";;
7500    esac
7501    vers=`sw_vers -productVersion | sed -e 's/^\([^.]*\)\.\([^.]*\).*/\1\2/'`
7502    arch=`arch`
7503    echo "$name$vers-$arch"
7504}
7505
7506pp_backend_macos_vas_platforms () {
7507    echo "osx"    # XXX non-really sure what they do.. it should be "macos"
7508}
7509pp_backend_macos_function () {
7510    case "$1" in
7511	_pp_macos_search_unused) cat<<'.';;
7512	    # Find an unused value in the given path
7513	    # args: path attribute minid [maxid]
7514		pp_tmp_val=$3
7515		while :; do
7516		    test $pp_tmp_val -ge ${4:-999999} && return 1
7517		    /usr/bin/dscl . -search "$1" "$2" $pp_tmp_val |
7518			grep . > /dev/null || break
7519		    pp_tmp_val=`expr $pp_tmp_val + 1`
7520		done
7521		echo $pp_tmp_val
7522.
7523        pp_mkgroup:depends) echo _pp_macos_search_unused;;
7524        pp_mkgroup) cat<<'.';;
7525	    set -e
7526	    /usr/bin/dscl . -read /Groups/"$1" >/dev/null 2>&1 && return
7527	    pp_tmp_gid=`_pp_macos_search_unused /Groups PrimaryGroupID 100`
7528	    /usr/bin/dscl . -create /Groups/"$1"
7529	    /usr/bin/dscl . -create /Groups/"$1" PrimaryGroupID $pp_tmp_gid
7530	    /usr/bin/dscl . -create /Groups/"$1" RealName "Group $1"
7531	    /usr/bin/dscl . -create /Groups/"$1" GroupMembership ""
7532	    /usr/bin/dscl . -create /Groups/"$1" Password '*'
7533.
7534        pp_mkuser:depends) echo pp_mkgroup _pp_macos_search_unused;;
7535        pp_mkuser) cat<<'.';;
7536	    set -e
7537	    /usr/bin/dscl . -read /Users/"$1" >/dev/null 2>&1 && return
7538	    pp_tmp_uid=`_pp_macos_search_unused /Users UniqueID 100`
7539	    pp_mkgroup "${2:-$1}"
7540	    pp_tmp_gid=`/usr/bin/dscl . -read /Groups/"${2:-$1}" \
7541		PrimaryGroupID | awk '{print $2}'`
7542	    /usr/bin/dscl . -create /Users/"$1"
7543	    /usr/bin/dscl . -create /Users/"$1" PrimaryGroupID $pp_tmp_gid
7544	    /usr/bin/dscl . -create /Users/"$1" NFSHomeDirectory \
7545				    "${3:-/var/empty}"
7546	    /usr/bin/dscl . -create /Users/"$1" UserShell \
7547				    "${4:-/usr/bin/false}"
7548	    /usr/bin/dscl . -create /Users/"$1" RealName "$1"
7549	    /usr/bin/dscl . -create /Users/"$1" UniqueID $pp_tmp_uid
7550	    /usr/bin/dscl . -create /Users/"$1" Password '*'
7551.
7552        pp_havelib) cat<<'.';;
7553	    # (use otool -L to find dependent libraries)
7554            for pp_tmp_dir in `echo "${3:+$3:}/usr/local/lib:/lib:/usr/lib" |
7555		    tr : ' '`; do
7556                test -r "$pp_tmp_dir/lib$1{$2:+.$2}.dylib" && return 0
7557            done
7558            return 1
7559.
7560	*) false;;
7561    esac
7562}
7563
7564pp_platforms="$pp_platforms inst"
7565
7566pp_backend_inst_detect () {
7567    case "$1" in
7568	IRIX*)	return 0;;
7569	*)	return 1;;
7570    esac
7571}
7572
7573pp_backend_inst_init () {
7574    pp_readlink_fn=pp_ls_readlink
7575}
7576
7577pp_backend_inst_create_idb()
7578{
7579    typeset t m o g f p st
7580
7581    while read t m o g f p st; do
7582        if test x"$o" = x"-"; then
7583            o="root"
7584        fi
7585        if test x"$g" = x"-"; then
7586            g="sys"
7587        fi
7588        case "$t" in
7589            f)  test x"$m" = x"-" && m=444
7590                echo "f 0$m $o $g $p $p $name.sw.base"
7591                ;;
7592            d)  test x"$m" = x"-" && m=555
7593                echo "d 0$m $o $g $p $p $name.sw.base"
7594                ;;
7595            s)  test x"$m" = x"-" && m=777
7596                test x"$m" = x"777" ||
7597                    pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
7598                echo "l 0$m $o $g $p $p $name.sw.base symval($st)"
7599                ;;
7600        esac
7601    done
7602}
7603
7604pp_backend_inst_create_spec()
7605{
7606    echo "product $name"
7607    echo "    id \"${summary}. Version: ${version}\""
7608    echo "    image sw"
7609    echo "        id \"Software\""
7610    echo "        version $version"
7611    echo "        order 9999"
7612    echo "        subsys base"
7613    echo "            id \"Base Software\""
7614    echo "            replaces self"
7615    echo "            exp $name.sw.base"
7616    echo "        endsubsys"
7617    echo "    endimage"
7618    echo "endproduct"
7619}
7620
7621pp_backend_inst () {
7622    curdir=`pwd`
7623
7624    cd "$pp_opt_wrkdir"
7625
7626    # initialize
7627    pp_inst_tardist=tardist
7628    pp_inst_spec=${name}.spec
7629    pp_inst_idb=${name}.idb
7630 
7631    rm -rf $pp_inst_tardist $pp_inst_spec $pp_inst_idb
7632    mkdir -p $pp_inst_tardist
7633
7634    # Create idb file
7635    (for _cmp in $pp_components; do
7636        cat  %files.$_cmp | sort +4u -6 | pp_backend_inst_create_idb
7637    done) >> $pp_inst_idb
7638
7639    pp_backend_inst_create_spec >> $pp_inst_spec
7640
7641    # Generate tardist
7642    gendist -verbose -all -root / -source $pp_opt_destdir -idb $pp_inst_idb -spec $pp_inst_spec -dist $pp_inst_tardist $name
7643    tar -cvf `pp_backend_inst_names` $pp_inst_tardist
7644
7645    cd "$curdir"
7646}
7647
7648pp_backend_inst_cleanup () {
7649    :
7650}
7651
7652pp_backend_inst_names () {
7653    echo ${name}-${version}.tardist
7654}
7655
7656pp_backend_inst_install_script () {
7657    :
7658}
7659
7660pp_backend_inst_function () {
7661    echo false
7662}
7663
7664pp_backend_inst_init_svc_vars () {
7665    :
7666}
7667
7668pp_backend_inst_probe () {
7669    cpu=`hinv|sed -n '/^CPU/{s/000 /k /;s/^CPU: //;s/ Process.*//;s/^MIPS //;p;q;}'|tr A-Z a-z`
7670    echo irix`uname -r`-$cpu
7671}
7672
7673pp_backend_inst_vas_platforms () {
7674    echo "irix-65"
7675}
7676
7677pp_platforms="$pp_platforms null"
7678
7679pp_backend_null_detect () {
7680    ! :
7681}
7682
7683pp_backend_null_init () {
7684    :
7685}
7686
7687
7688pp_backend_null () {
7689    :
7690}
7691
7692pp_backend_null_cleanup () {
7693    :
7694}
7695
7696pp_backend_null_names () {
7697    :
7698}
7699
7700pp_backend_null_install_script () {
7701    :
7702}
7703
7704pp_backend_null_function () {
7705    echo false
7706}
7707
7708pp_backend_null_init_svc_vars () {
7709    :
7710}
7711
7712pp_backend_null_probe () {
7713    echo unknown-unknown
7714}
7715
7716pp_backend_null_vas_platforms () {
7717:
7718}
7719
7720
7721quest_require_vas () {
7722    typeset v d
7723
7724    if test $# -ne 1; then
7725        return
7726    fi
7727    set -- `echo "$1" | tr . ' '` 0 0 0
7728
7729    for d
7730    do
7731        echo $d | grep '^[0-9][0-9]*$' > /dev/null ||
7732            pp_error "quest_require_vas: Bad version component $d"
7733    done
7734
7735    test $# -lt 4 &&
7736            pp_error "quest_require_vas: missing version number"
7737
7738    case "$1.$2.$3.$4" in
7739        *.0.0.0) v=$1;;
7740        *.*.0.0) v=$1.$2;;
7741        *.*.*.0) v=$1.$2.$3;;
7742        *)       v=$1.$2.$3.$4;;
7743    esac
7744
7745    cat <<.
7746        if test -x /opt/quest/bin/vastool &&
7747           /opt/quest/bin/vastool -v |
7748            awk 'NR == 1 {print \$4}' |
7749            awk -F. '{ if (\$1<$1 || \$1==$1 && ( \
7750                           \$2<$2 || \$2==$2 && ( \
7751                           \$3<$3 || \$2==$3 && ( \
7752                           \$4<$4 )))) exit(1); }'
7753        then
7754            exit 0
7755        else
7756            echo "Requires VAS $v or later"
7757            exit 1
7758        fi
7759.
7760}
7761pp_main ${1+"$@"}
7762