Merge commit 'upstream/1.7.4p5'
[debian/sudo] / pp
1 #!/bin/sh
2 # (c) 2010 Quest Software, Inc. All rights reserved
3 pp_revision="283"
4  # Copyright 2010 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
33 pp_version="1.0.0.$pp_revision"
34 pp_copyright="Copyright 2010, Quest Software, Inc. All rights reserved."
35
36 pp_opt_debug=false
37 pp_opt_destdir="$DESTDIR"
38 pp_opt_install_script=
39 pp_opt_list=false
40 pp_opt_no_clean=false
41 pp_opt_no_package=false
42 pp_opt_only_front=false
43 pp_opt_platform=
44 pp_opt_probe=false
45 pp_opt_strip=false
46 pp_opt_save_unstripped=false
47 pp_opt_vas_platforms=false
48 pp_opt_wrkdir="`pwd`/pp.work.$$"
49 pp_opt_verbose=false
50 pp_opt_version=false
51 pp_opt_input="-"
52 pp_opt_init_vars=""
53 pp_opt_eval=
54
55 test -n "$PP_NO_CLEAN" && pp_opt_no_clean=true
56 test -n "$PP_DEBUG" && pp_opt_debug=true
57 test -n "$PP_VERBOSE" && pp_opt_verbose=true
58
59 pp_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
77 pp_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
172 polypkg $pp_version $pp_copyright
173 usage: $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
196 pp_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
258 pp_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
266 pp_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
315 pp_errors=false
316
317 if 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
321 else
322    pp_col_redfg='['
323    pp_col_bluefg='['
324    pp_col_reset=']'
325 fi
326
327 pp__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
335 pp_warn () {
336         pp__warn "pp: ${pp_col_redfg}warning${pp_col_reset}" "$*"
337 }
338
339 pp_error () {
340         pp__warn "pp: ${pp_col_redfg}error${pp_col_reset}" "$*"
341         pp_errors=true
342 }
343
344 pp_die () {
345         pp_error "$@"
346         exit 1
347 }
348
349 pp_die_if_errors () {
350         $pp_errors && pp_die "$@"
351 }
352
353 pp_debug () {
354         $pp_opt_debug && echo "${pp_col_bluefg}debug${pp_col_reset} $*" >&2
355 }
356
357 pp_verbose () {
358         $pp_opt_verbose && echo "pp: ${pp_col_bluefg}info${pp_col_reset} $*" >&2
359         "$@";
360 }
361
362 pp_substitute () {
363   sed -e 's,%(\([^)]*\)),\16\15`\1`\16,g' \
364       -e 's,%{\([^}]*\)},\16\15${\1}\16,g' \
365       -e 's,$,\17,' |
366   tr '\16' '\012' |
367   sed -e '/^[^\15]/s/["$`\\]/\\&/g' \
368       -e 's/^\15//' \
369       -e '1s/^/echo "/' \
370       -e '$s,\17$,",' \
371       -e 's,\17,"\16echo ",g' |
372   tr -d '\012' |
373   tr '\16' '\012'
374   echo
375 }
376
377 pp_incr () {
378     eval "$1=\`expr \$$1 + 1\`"
379 }
380
381 pp_decr () {
382     eval "$1=\`expr \$$1 - 1\`"
383 }
384
385 pp_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
392 pp_contains () {
393     case " $1 " in
394        *" $2 "*) return 0;;
395        *) return 1;;
396     esac
397 }
398
399 pp_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
409 pp_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
419 pp_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
429 pp_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
439 pp_mode_strip_altaccess () {
440     case "$1" in
441         ??????????[+.])
442             echo `echo "$1" | cut -b -10`;;
443         *)
444             echo "$1";;
445     esac
446 }
447
448 pp_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
504 pp_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
519 pp_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
532 pp_note_file_used() {
533     echo "$1" >> $pp_wrkdir/all.files
534 }
535
536 pp_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
551 pp_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
566 pp_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
574 pp_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
582 pp_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
591 pp_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
607 pp_readlink() {
608
609 pp_debug "&& pp_readlink_fn=$pp_readlink_fn"
610
611     if test -n "$pp_readlink_fn"; then
612 pp_debug "&& calling $pp_readlink_fn $*"
613         "$pp_readlink_fn" "$@"
614     else
615         readlink "$@"
616     fi
617 }
618
619
620 pp_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
672 pp_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
703 pp_function () {
704     pp_functions "$1"
705 }
706
707 pp_makevar () {
708     #-- convert all non alpha/digits to underscores
709     echo "$*" | tr -c '[a-z][A-Z][0-9]\012' '[_*]'
710 }
711
712 pp_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
717 pp_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
722 pp_backend_function_getopt () {
723     cat <<'..'
724 pp_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
755 pp_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
765 pp_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
771 pp_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
797 pp_if_true=0
798 pp_if_false=0
799
800 pp_frontend_init () {
801     name=
802     version=
803     summary="no summary"
804     description="No description"
805     copyright="Copyright 2010 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
813 pp_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
824 pp_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
844 pp_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
892 pp_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)
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.*|%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      esac
1096   done
1097   exec <&-
1098
1099   if test $pp_if_true != 0 -o $pp_if_false != 0; then
1100         pp_die "missing %endif at end of file"
1101   fi
1102
1103   pp_lineno=
1104
1105   pp_debug " name        = $name"
1106   pp_debug " version     = $version"
1107   pp_debug " summary     = $summary"
1108   pp_debug " description = $description"
1109   pp_debug " copyright   = $copyright"
1110   pp_debug ""
1111   pp_debug "\$pp_components: $pp_components"
1112   pp_debug "\$pp_services:   $pp_services"
1113 }
1114
1115 pp_set_api_version() {
1116     case "$1" in
1117         1.0)    : ;;
1118         *)      pp_error "This version of polypackage is too old";;
1119     esac
1120 }
1121
1122 pp_platform=
1123
1124 pp_set_platform () {
1125     if test -n "$pp_opt_platform"; then
1126         pp_contains "$pp_platforms" "$pp_opt_platform" ||
1127                 pp_die "$pp_opt_platform: unknown platform"
1128         pp_platform="$pp_opt_platform"
1129     else
1130         uname_s=`uname -s 2>/dev/null`
1131         pp_platform=
1132         for p in $pp_platforms; do
1133             pp_debug "probing for platform $p"
1134             if eval pp_backend_${p}_detect "$uname_s"; then
1135                 pp_platform="$p"
1136                 break;
1137             fi
1138         done
1139         test -z "$pp_platform" &&
1140                 pp_die "cannot detect platform (supported: $pp_platforms)"
1141     fi
1142     pp_debug "pp_platform = $pp_platform"
1143 }
1144
1145 pp_expand_path=
1146
1147 pp_expand_test_usr_bin () {
1148         awk '$1 == "/usr" || $2 == "/usr" {usr++}
1149              $1 == "/bin" || $2 == "/bin" {bin++}
1150              END { if (usr == 1 && bin == 1) exit(0); else exit(1); }'
1151 }
1152
1153 pp_set_expand_converter_or_reexec () {
1154     test -d /usr -a -d /bin ||
1155         pp_die "missing /usr or /bin"
1156     echo /usr /bin | pp_expand_test_usr_bin || pp_die "pp_expand_test_usr_bin?"
1157     if (eval "echo /{usr,bin}" | pp_expand_test_usr_bin) 2>/dev/null; then
1158         pp_expand_path=pp_expand_path_brace
1159     elif (eval "echo /@(usr|bin)" | pp_expand_test_usr_bin) 2>/dev/null; then
1160         pp_expand_path=pp_expand_path_at
1161     else
1162         test x"$pp_expand_rexec" != x"true" ||
1163             pp_die "problem finding shell that can do brace expansion"
1164         for shell in ksh ksh93 bash; do
1165             if ($shell -c 'echo /{usr,bin}' |
1166                         pp_expand_test_usr_bin) 2>/dev/null ||
1167                ($shell -c 'echo /@(usr|bin)' |
1168                         pp_expand_test_usr_bin) 2>/dev/null
1169             then
1170                 pp_debug "switching to shell $shell"
1171                 pp_expand_rexec=true exec $shell "$0" "$@"
1172             fi
1173         done
1174         pp_die "cannot find a shell that does brace expansion"
1175     fi
1176 }
1177
1178 pp_expand_path_brace () {
1179         typeset f
1180         eval "for f in $1; do echo \"\$f\"; done|sort -u"
1181 }
1182
1183 pp_expand_path_at () {
1184         typeset f
1185         eval "for f in `
1186             echo "$1" | sed -e 's/{/@(/g' -e 's/}/)/g' -e 's/,/|/g'
1187                 `; do echo \"\$f\"; done|sort -u"
1188 }
1189
1190 pp_shlib_suffix='.so*'
1191
1192 pp_model_init () {
1193     #@ $pp_components: whitespace-delimited list of components seen in %files
1194     pp_components=
1195     #@ $pp_services: whitespace-delimited list of %service seen
1196     pp_services=
1197
1198     rm -f $pp_wrkdir/%files.* \
1199           $pp_wrkdir/%post.* \
1200           $pp_wrkdir/%pre.* \
1201           $pp_wrkdir/%preun.* \
1202           $pp_wrkdir/%postup.* \
1203           $pp_wrkdir/%postun.* \
1204           $pp_wrkdir/%service.* \
1205           $pp_wrkdir/%set \
1206           $pp_wrkdir/%fixup
1207 }
1208
1209
1210 pp_have_component () {
1211         pp_contains "$pp_components" "$1"
1212 }
1213
1214 pp_have_all_components () {
1215         pp_contains_all "$pp_components" "$@"
1216 }
1217
1218 pp_add_component () {
1219         pp_add_to_list 'pp_components' "$1"
1220 }
1221
1222 pp_add_service () {
1223         pp_add_to_list 'pp_services' "$1"
1224 }
1225
1226 pp_service_init_vars () {
1227         cmd=
1228         pidfile=
1229         stop_signal=15          # SIGTERM
1230         user=root
1231         group=
1232         enable=yes              # make it so the service starts on boot
1233         optional=no             # Whether installing this service is optional
1234         pp_backend_init_svc_vars
1235 }
1236
1237 pp_service_check_vars () {
1238         test -n "$cmd" ||
1239                 pp_error "%service $1: cmd not defined"
1240         case "$enable" in
1241             yes|no) : ;;
1242             *) pp_error "%service $1: \$enable must be set to yes or no";;
1243         esac
1244 }
1245
1246 pp_load_service_vars () {
1247         pp_service_init_vars
1248         . "$pp_wrkdir/%service.$1"
1249         pp_service_check_vars "$1"
1250 }
1251
1252 pp_files_expand () {
1253     typeset _p _mode _group _owner _flags _path _optional _has_target _tree
1254     typeset _path _file _tgt _m _o _g _f _type _lm _ll _lo _lg _ls _lx
1255     typeset _ignore _a
1256
1257     test $# -eq 0 && return
1258
1259     pp_debug "pp_files_expand: path is: $1"
1260
1261     case "$1" in "#"*) return;; esac
1262     _p="$1"; shift
1263
1264     pp_debug "pp_files_expand: other arguments: $*"
1265
1266     #-- the mode must be an octal number of at least three digits
1267     _mode="="
1268     _a=`eval echo \"$1\"`
1269     case "$_a" in
1270         *:*) :;;
1271         -|=|[01234567][01234567][01234567]*) _mode="$_a"; shift;;
1272     esac
1273
1274     #-- the owner:group field may have optional parts
1275     _a=`eval echo \"$1\"`
1276     case "$_a" in
1277         *:*) _group=${_a#*:}; _owner=${_a%:*}; shift;;
1278         =|-) _group=$_a;      _owner=$_a; shift;;
1279         *)   _group=;         _owner=;;
1280     esac
1281
1282     #-- process the flags argument
1283     _flags=
1284     _optional=false
1285     _has_target=false
1286     _ignore=false
1287     if test $# -gt 0; then
1288         _a=`eval echo \"$1\"`
1289         case ",$_a," in *,volatile,*) _flags="${_flags}v";; esac
1290         case ",$_a," in *,optional,*) _optional=true;; esac
1291         case ",$_a," in *,symlink,*) _has_target=true;; esac
1292         case ",$_a," in *,ignore-others,*) _flags="${_flags}i";; esac
1293         case ",$_a," in *,ignore,*) _ignore=true;; esac
1294         shift
1295     fi
1296
1297     #-- process the target argument
1298     if $_has_target; then
1299         test $# -ne 0 || pp_error "$_p: missing target"
1300         _a=`eval echo \"$1\"`
1301         _target="$_a"
1302         shift
1303     fi
1304
1305     pp_debug "pp_files_expand: $_mode|$_owner:$_group|$_flags|$_target|$*"
1306
1307     test $# -eq 0 || pp_error "$_p: too many arguments"
1308
1309     #-- process speciall suffixes
1310     tree=
1311     case "$_p" in
1312         *"/**")  _p="${_p%"/**"}"; tree="**";;
1313         *".%so") _p="${_p%".%so"}$pp_shlib_suffix";;
1314     esac
1315
1316     #-- expand the path using the shell glob
1317     pp_debug "expanding .$_p ... with $pp_expand_path"
1318     (cd ${pp_destdir} && $pp_expand_path ".$_p") > $pp_wrkdir/tmp.files.exp
1319
1320     #-- expand path/** by rewriting the glob output file
1321     case "$tree" in
1322         "") : ;;
1323         "**")
1324             pp_debug "expanding /** tree ..."
1325             while read _path; do
1326                 _path="${_path#.}"
1327                 pp_find_recurse "$pp_destdir${_path%/}"
1328             done < $pp_wrkdir/tmp.files.exp |
1329                  sort -u > $pp_wrkdir/tmp.files.exp2
1330             mv $pp_wrkdir/tmp.files.exp2 $pp_wrkdir/tmp.files.exp
1331             ;;
1332     esac
1333
1334     while read _path; do
1335         _path="${_path#.}"
1336         _file="${pp_destdir}${_path}"
1337         _tgt=
1338         _m="$_mode"
1339         _o="${_owner:--}"
1340         _g="${_group:--}"
1341         _f="$_flags"
1342
1343         case "$_path" in
1344             /*) :;;
1345             *)  pp_warn "$_path: inserting leading /"
1346                 _path="/$_path";;  # ensure leading /
1347         esac
1348
1349         #-- sanity checks
1350         case "$_path" in
1351             */../*|*/..) pp_error "$_path: invalid .. in path";;
1352             */./*|*/.)   pp_warn  "$_path: invalid component . in path";;
1353             *//*)        pp_warn  "$_path: redundant / in path";;
1354         esac
1355
1356         #-- set the type based on the real file's type
1357         if $_ignore; then
1358            _type=f _m=_ _o=_ _g=_
1359         elif test -h "$_file"; then
1360            case "$_path" in
1361                 */) pp_warn "$_path (symlink $_file): removing trailing /"
1362                     _path="${_path%/}"
1363                     ;;
1364            esac
1365            _type=s
1366            if test x"$_target" != x"=" -a -n "$_target"; then
1367                _tgt="$_target"
1368 pp_debug "symlink target is $_tgt"
1369            else
1370                _tgt=`pp_readlink "$_file"`;
1371                test -z "$_tgt" && pp_error "can't readlink $_file"
1372                case "$_tgt" in
1373                     ${pp_destdir}/*)
1374                        pp_warn "stripped \$destdir from symlink ($_path)"
1375                        _tgt="${_tgt#$pp_destdir}";;
1376                esac
1377            fi
1378            _m=777
1379         elif test -d "$_file"; then
1380            #-- display a warning if the user forgot the trailing /
1381            case "$_path" in
1382                 */) :;;
1383                 *) pp_warn "$_path (matching $_file): adding trailing /"
1384                    _path="$_path/";;
1385            esac
1386            _type=d
1387            $_has_target && pp_error "$_file: not a symlink"
1388         elif test -f "$_file"; then
1389            case "$_path" in
1390                 */) pp_warn "$_path (matching $_file): removing trailing /"
1391                     _path="${_path%/}"
1392                     ;;
1393            esac
1394            _type=f
1395            $_has_target && pp_error "$_file: not a symlink"
1396         else
1397            $_optional && continue
1398            pp_error "$_file: missing"
1399            _type=f
1400         fi
1401
1402         #-- convert '=' shortcuts into mode/owner/group from ls
1403         case ":$_m:$_o:$_g:" in *:=:*)
1404             if LS_OPTIONS=--color=never /bin/ls -ld "$_file" \
1405                     > $pp_wrkdir/ls.tmp
1406             then
1407                 read _lm _ll _lo _lg _ls _lx < $pp_wrkdir/ls.tmp
1408                 test x"$_m" = x"=" && _m=`pp_mode_from_ls "$_lm"`
1409                 test x"$_o" = x"=" && _o="$_lo"
1410                 test x"$_g" = x"=" && _g="$_lg"
1411             else
1412                 pp_error "cannot read $_file"
1413                 test x"$_m" = x"=" && _m=-
1414                 test x"$_o" = x"=" && _o=-
1415                 test x"$_g" = x"=" && _g=-
1416             fi
1417             ;;
1418         esac
1419
1420         test -n "$_f" || _f=-
1421
1422         #-- sanity checks
1423         test -n "$_type" || pp_die "_type empty"
1424         test -n "$_path" || pp_die "_path empty"
1425         test -n "$_m" || pp_die "_m empty"
1426         test -n "$_o" || pp_die "_o empty"
1427         test -n "$_g" || pp_die "_g empty"
1428
1429         #-- setuid/gid files must be given an explicit owner/group (or =)
1430         case "$_o:$_g:$_m" in
1431             -:*:[4657][1357]??|-:*:[4657]?[1357]?|-:*:[4657]??[1357])
1432                 pp_error "$_path: setuid file ($_m) missing explicit owner";;
1433             *:-:[2367][1357]??|*:-:[2367]?[1357]?|*:-:[2367]??[1357])
1434                 pp_error "$_path: setgid file ($_m) missing explicit group";;
1435         esac
1436
1437         # convert numeric uids into usernames; only works for /etc/passwd
1438         case "$_o" in [0-9]*) _o=`pp_getpwuid $_o`;; esac
1439         case "$_g" in [0-9]*) _g=`pp_getgrgid $_g`;; esac
1440
1441         pp_debug "$_type $_m $_o $_g $_f $_path" $_tgt
1442         $_ignore || echo "$_type $_m $_o $_g $_f $_path" $_tgt
1443         pp_note_file_used "$_path"
1444         case "$_f" in *i*) echo "$_path" >> $pp_wrkdir/ign.files;; esac
1445     done < $pp_wrkdir/tmp.files.exp
1446 }
1447
1448 pp_files_check_duplicates () {
1449     typeset _path
1450     if test -s $pp_wrkdir/all.files; then
1451         sort < $pp_wrkdir/all.files | uniq -d > $pp_wrkdir/duplicate.files
1452         if test -f $pp_wrkdir/ign.awk; then
1453             # Remove ignored files
1454             mv $pp_wrkdir/duplicate.files $pp_wrkdir/duplicate.files.ign
1455             sed -e 's/^/_ _ _ _ _ /' < $pp_wrkdir/duplicate.files.ign |
1456                 awk -f $pp_wrkdir/ign.awk |
1457                 sed -e 's/^_ _ _ _ _ //' > $pp_wrkdir/duplicate.files
1458         fi
1459         while read _path; do
1460             pp_warn "$_path: file declared more than once"
1461         done <$pp_wrkdir/duplicate.files
1462     fi
1463 }
1464
1465 pp_files_check_coverage () {
1466     pp_find_recurse "$pp_destdir" | sort > $pp_wrkdir/coverage.avail
1467     if test -s $pp_wrkdir/all.files; then
1468         sort -u < $pp_wrkdir/all.files
1469     else
1470         :
1471     fi > $pp_wrkdir/coverage.used
1472     join -v1 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
1473         > $pp_wrkdir/coverage.not-packaged
1474     if test -s $pp_wrkdir/coverage.not-packaged; then
1475         pp_warn "The following files/directories were found but not packaged:"
1476         sed -e 's,^,    ,' <  $pp_wrkdir/coverage.not-packaged >&2
1477     fi
1478     join -v2 $pp_wrkdir/coverage.avail $pp_wrkdir/coverage.used \
1479         > $pp_wrkdir/coverage.not-avail
1480     if test -s $pp_wrkdir/coverage.not-avail; then
1481         pp_warn "The following files/directories were named but not found:"
1482         sed -e 's,^,    ,' <  $pp_wrkdir/coverage.not-avail >&2
1483     fi
1484 }
1485
1486 pp_files_ignore_others () {
1487     typeset p f
1488
1489     test -s $pp_wrkdir/ign.files || return
1490
1491     #-- for each file in ign.files, we remove it from all the
1492     #   other %files.* lists, except where it has an i flag.
1493     #   rather than scan each list multiple times, we build
1494     #   an awk script
1495
1496     pp_debug "stripping ignore files"
1497
1498     while read p; do
1499         echo '$6 == "'"$p"'" && $5 !~ /i/ { next }'
1500     done < $pp_wrkdir/ign.files > $pp_wrkdir/ign.awk
1501     echo '{ print }' >> $pp_wrkdir/ign.awk
1502
1503     $pp_opt_debug && cat $pp_wrkdir/ign.awk
1504
1505     for f in $pp_wrkdir/%files.*; do
1506         mv $f $f.ign
1507         awk -f $pp_wrkdir/ign.awk < $f.ign > $f || pp_error "awk"
1508     done
1509 }
1510
1511 pp_service_scan_groups () {
1512     typeset svc
1513
1514     #-- scan for "group" commands, and build a list of groups
1515     pp_service_groups=
1516     if test -n "$pp_services"; then
1517         for svc in $pp_services; do
1518             group=
1519             . $pp_wrkdir/%service.$svc
1520             if test -n "$group"; then
1521                 pp_contains "$pp_services" "$group" && pp_error \
1522                     "%service $svc: group name $group in use by a service"
1523                 pp_add_to_list 'pp_service_groups' "$group"
1524                 echo "$svc" >> $pp_wrkdir/%svcgrp.$group
1525             fi
1526         done
1527     fi
1528 }
1529
1530 pp_service_get_svc_group () {
1531     (tr '\012' ' ' < $pp_wrkdir/%svcgrp.$1 ; echo) | sed -e 's/ $//'
1532 }
1533
1534 for _sufx in _init '' _names _cleanup _install_script \
1535     _init_svc_vars _function _probe _vas_platforms
1536 do
1537  eval "pp_backend$_sufx () { pp_debug pp_backend$_sufx; pp_backend_\${pp_platform}$_sufx \"\$@\"; }"
1538 done
1539
1540
1541 pp_platforms="$pp_platforms aix"
1542
1543 pp_backend_aix_detect () {
1544         test x"$1" = x"AIX"
1545 }
1546
1547 pp_backend_aix_init () {
1548         pp_aix_detect_arch
1549         pp_aix_detect_os
1550
1551         pp_aix_bosboot=         # components that need bosboot
1552         pp_aix_lang=en_US
1553         pp_aix_copyright=
1554         pp_aix_start_services_after_install=false
1555         pp_aix_init_services_after_install=true
1556
1557         case "$pp_aix_os" in
1558             *) pp_readlink_fn=pp_ls_readlink;;  # XXX
1559         esac
1560
1561         pp_aix_abis_seen=
1562 }
1563
1564 pp_aix_detect_arch () {
1565         pp_aix_arch_p=`uname -p 2>/dev/null`
1566         case "$pp_aix_arch_p"  in
1567            "")      pp_debug "can't get processor type from uname -p"
1568                     pp_aix_arch_p=powerpc
1569                     pp_aix_arch=R;;  # guess (lsattr -l proc0 ??)
1570            powerpc) pp_aix_arch=R;;
1571            *)       pp_aix_arch_p=intel
1572                     pp_aix_arch=I;;  # XXX? verify
1573         esac
1574
1575         case "`/usr/sbin/lsattr -El proc0 -a type -F value`" in
1576             PowerPC_POWER*) pp_aix_arch_std=ppc64;;
1577             PowerPC*) pp_aix_arch_std=ppc;;
1578             *) pp_aix_arch_std=unknown;;
1579         esac
1580 }
1581
1582 pp_aix_detect_os () {
1583         typeset r v
1584
1585         r=`uname -r`
1586         v=`uname -v`
1587         pp_aix_os=aix$v$r
1588 }
1589
1590 pp_aix_version_fix () {
1591     typeset v
1592     v=`echo $1 | tr -c -d '[0-9].\012'`
1593     if test x"$v" != x"$1"; then
1594         pp_warn "stripped version '$1' to '$v'"
1595     fi
1596     case $v in
1597         ""|*..*|.*|*.) pp_error "malformed '$1'"
1598                  echo "0.0.0.0";;
1599         *.*.*.*.*)
1600                  # 5 components are only valid for fileset updates, not base
1601                  # filesets (full packages). We trim 5+ components down to 4.
1602                  pp_warn "version '$1' has too many dots for AIX, truncating"
1603                  echo "$v" | cut -d. -f1-4;;
1604         *.*.*.*) echo "$v";;
1605         *.*.*) echo "$v.0";;
1606         *.*) echo "$v.0.0";;
1607         *) echo "$v.0.0.0";;
1608     esac
1609 }
1610
1611 pp_aix_select () {
1612         case "$1" in
1613             -user) op="";;
1614             -root) op="!";;
1615             *) pp_die "pp_aix_select: bad argument";;
1616         esac
1617         #pp_debug awk '$5 '$op' /^\/(usr|opt)(\/|$)/ { print; }'
1618         #awk '$5 '$op' /^\/(usr|opt)(\/|$)/ { print; }'
1619         awk $op'($6 ~ /^\/usr\// || $6 ~ /^\/opt\//) { print; }'
1620 }
1621
1622 pp_aix_copy_root () {
1623     typeset t m o g f p st target
1624     while read t m o g f p st; do
1625         case "$t" in
1626            d) pp_create_dir_if_missing "$1${p%/}";;
1627            f) pp_add_transient_file "$1$p"
1628               pp_verbose ln "$pp_destdir$p" "$pp_destdir$1$p" ||
1629                 pp_error "can't link $p into $1";;
1630            *) pp_warn "pp_aix_copy_root: filetype $t not handled";;
1631         esac
1632     done
1633 }
1634
1635
1636 pp_aix_size () {
1637     typeset prefix t m o g f p st
1638
1639     prefix="$1"
1640     while read t m o g f p st; do
1641       case "$t" in f) du -a "$pp_destdir$p";; esac
1642     done | sed -e 's!/[^/]*$!!' | sort +1 |
1643     awk '{ if ($2 != d)
1644            { if (sz) print d,sz;
1645              d=$2; sz=0 }
1646            sz += $1; }
1647          END { if (sz) print d,sz }' |
1648     sed -n -e "s!^$pp_destdir!$prefix!p"
1649 }
1650
1651 pp_aix_list () {
1652     awk '{ print "." pfx $6; }' pfx="$1"
1653 }
1654
1655 pp_aix_make_liblpp () {
1656     typeset out dn fl f
1657
1658     out="$1"; shift
1659     dn=`dirname "$2"`
1660     fl=
1661     for f
1662     do
1663         case "$f" in "$dn/"*) fl="$fl `basename $f`" ;;
1664                      *) pp_die "liblpp name $f not in $dn/";; esac
1665     done
1666     (cd "$dn" && pp_verbose  ar -c -g -r "$out" $fl) || pp_error "ar error"
1667 }
1668
1669 pp_aix_make_script () {
1670     rm -f "$1"
1671     echo "#!/bin/sh" > "$1"
1672     cat >> "$1"
1673     echo "exit 0" >> "$1"
1674     chmod +x "$1"
1675 }
1676
1677 pp_aix_inventory () {
1678     typeset fileset t m o g f p st type
1679
1680     fileset="$1"
1681     while read t m o g f p st; do
1682       case "$p" in *:*) pp_error "path $p contains colon";; esac
1683       echo "$p:"
1684       case "$t" in
1685         f)   type=FILE;      defm=644 ;;
1686         s)   type=SYMLINK;   defm=777 ;;
1687         d)   type=DIRECTORY; defm=755 ;;
1688       esac
1689       echo " type = $type"
1690       echo " class = inventory,apply,$fileset"
1691       set -- `/bin/ls -ld "$pp_destdir$p" 2>/dev/null`
1692       owner=$3 group=$4 size=$5
1693       if test x"$m" = x"-"; then m="$defm"; fi
1694       if test x"$o" = x"-"; then o="root"; fi
1695       if test x"$g" = x"-"; then g="system"; fi
1696       echo " owner = $o"
1697       echo " group = $g"
1698
1699       case "$m" in ????)
1700         m=`echo $m|sed -e 's/^1/TCB,/' \
1701                        -e 's/^[23]/TCB,SGID,/' \
1702                        -e 's/^[45]/TCB,SUID,/' \
1703                        -e 's/^[67]/TCB,SUID,SGID,/'`;;  # vtx bit ignored
1704       esac
1705       echo " mode = $m"
1706       case "$t" in
1707         f) if test ! -f "$pp_destdir$p"; then
1708                 pp_error "$p: missing file"
1709            fi
1710            case "$flags" in
1711             *v*)
1712               echo " size = VOLATILE"
1713               echo " checksum = VOLATILE"
1714               ;;
1715             *)
1716               if test -r "$pp_destdir$p"; then
1717                 echo " size = $size"
1718                 pp_verbose  sum -r < "$pp_destdir$p" |
1719                   sed -e 's/.*/ checksum = "&"/'
1720               fi
1721               ;;
1722            esac;;
1723         s)
1724            echo " target = $st"
1725            ;;
1726       esac
1727
1728       #-- Record ABI types seen
1729       case "$t" in
1730         f) if test -r "$pp_destdir$p"; then
1731             case "`file "$pp_destdir$p"`" in
1732                 *"executable (RISC System/6000)"*) abi=ppc;;
1733                 *"64-bit XCOFF executable"*)       abi=ppc64;;
1734                 *) abi=;;
1735             esac
1736             if test -n "$abi"; then
1737                 pp_add_to_list pp_aix_abis_seen $abi
1738             fi
1739            fi;;
1740       esac
1741
1742     done
1743 }
1744
1745 pp_aix_depend ()
1746 {
1747     if test -s "$1"; then
1748        pp_warn "aix dependencies not implemented"
1749     fi
1750 }
1751
1752 pp_aix_add_service () {
1753         typeset svc cmd_cmd cmd_arg f
1754         svc="$1"
1755
1756         pp_load_service_vars $svc
1757
1758         set -- $cmd
1759         cmd_cmd="$1"; shift
1760         cmd_arg="$pp_aix_mkssys_cmd_args";
1761
1762         case "$stop_signal" in
1763                 HUP) stop_signal=1;;
1764                 INT) stop_signal=2;;
1765                 QUIT) stop_signal=3;;
1766                 KILL) stop_signal=9;;
1767                 TERM) stop_signal=15;;
1768                 USR1) stop_signal=30;;
1769                 USR2) stop_signal=31;;
1770                 "")
1771                   pp_error "%service $svc: stop_signal not set";;
1772                 [a-zA-Z]*)
1773                   pp_error "%service $svc: bad stop_signal ($stop_signal)";;
1774         esac
1775
1776         test -z "$pidfile" || pp_error "aix requires empty pidfile (non daemon)"
1777
1778         pp_add_component run
1779         if test "$user" = "root"; then
1780             uid=0
1781         else
1782             uid="\"\`/usr/bin/id -u $user\`\""
1783         fi
1784
1785
1786         #-- add command text to create/remove the service
1787         cat <<-. >> $pp_wrkdir/%post.$svc
1788 svc=$svc
1789 uid=0
1790 cmd_cmd=$daemon
1791 cmd_arg="$cmd_arg"
1792 stop_signal=$stop_signal
1793 force_signal=9
1794 srcgroup="$pp_aix_mkssys_group"
1795
1796 lssrc -s \$svc > /dev/null 2>&1
1797 if [ \$? -eq 0 ]; then
1798   lssrc -s \$svc | grep "active" > /dev/null 2>&1
1799   if [ \$? -eq 0 ]; then
1800     stopsrc -s \$svc > /dev/null 2>&1
1801   fi
1802   rmsys -s \$svc > /dev/null 2>&1
1803 fi
1804
1805 mkssys -s \$svc -u \$uid -p "\$cmd_cmd" \${cmd_arg:+-a "\$cmd_arg"} -S -n \$stop_signal -f 9 ${pp_aix_mkssys_args} \${srcgroup:+-G \$srcgroup}
1806 .
1807
1808         #-- add code to start the service on reboot
1809         ${pp_aix_init_services_after_install} &&
1810           cat <<-. >> $pp_wrkdir/%post.$svc
1811 mkitab "\$svc:2:once:/usr/bin/startsrc -s \$svc" > /dev/null 2>&1
1812 .
1813
1814         ${pp_aix_start_services_after_install} &&
1815           cat <<-. >> $pp_wrkdir/%post.$svc
1816 startsrc -s \$svc
1817 .
1818
1819 if [ -f "$pp_wrkdir/%post.run" ];then
1820     cat $pp_wrkdir/%post.run >> $pp_wrkdir/%post.$svc
1821 fi
1822 mv $pp_wrkdir/%post.$svc $pp_wrkdir/%post.run
1823
1824
1825         ${pp_aix_init_services_after_install} &&
1826            pp_prepend $pp_wrkdir/%preun.$svc <<-.
1827 rmitab $svc
1828 .
1829         pp_prepend $pp_wrkdir/%preun.$svc <<-.
1830 stopsrc -s $svc >/dev/null 2>&1
1831 rmssys -s $svc
1832 .
1833
1834 if [ -f "$pp_wrkdir/%preun.run" ];then
1835     cat $pp_wrkdir/%preun.run >> $pp_wrkdir/%preun.$svc
1836 fi
1837 mv $pp_wrkdir/%preun.$svc $pp_wrkdir/%preun.run
1838 }
1839
1840 pp_backend_aix () {
1841         typeset briefex instuser instroot svc cmp outbff
1842         typeset user_wrkdir root_wrkdir
1843         typeset user_files root_files
1844
1845         test -n "$pp_destdir" ||
1846            pp_error "AIX backend requires the '--destdir' option"
1847
1848         instuser="/usr/lpp/$name"
1849         instroot="$instuser/inst_root"
1850         pp_aix_bff_name=${pp_aix_bff_name:-$name}
1851
1852         # Here is the component mapping:
1853         #  run -> $pp_aix_bff_name.rte ('Run time environment')
1854         #  doc -> $pp_aix_bff_name.doc (non-standard)
1855         #  dev -> $pp_aix_bff_name.adt ('Application developer toolkit')
1856         #  dbg -> $pp_aix_bff_name.diag ('Diagnostics')
1857
1858         test `echo "$summary" | wc -c ` -gt 40 && pp_error "\$summary too long"
1859
1860         user_wrkdir=$pp_wrkdir/u
1861         root_wrkdir=$pp_wrkdir/r
1862         pp_verbose  rm -rf $user_wrkdir $root_wrkdir
1863         pp_verbose  mkdir -p $user_wrkdir $root_wrkdir
1864
1865         for svc in $pp_services .; do
1866             test . = "$svc" && continue
1867             pp_aix_add_service $svc
1868         done
1869
1870         {
1871           echo "4 $pp_aix_arch I $name {"
1872
1873           for cmp in $pp_components; do
1874             case "$cmp" in
1875                 run) ex=rte  briefex="runtime";;
1876                 doc) ex=doc  briefex="documentation";;
1877                 dev) ex=adt  briefex="developer toolkit";;
1878                 dbg) ex=diag briefex="diagnostics";;
1879             esac
1880
1881             user_files=$pp_wrkdir/%files.$cmp.u
1882             root_files=$pp_wrkdir/%files.$cmp.r
1883
1884             pp_aix_select -user < $pp_wrkdir/%files.$cmp > $user_files
1885             pp_aix_select -root < $pp_wrkdir/%files.$cmp > $root_files
1886
1887             # Default to USR only unless there are root files,
1888             # or a post/pre/check script associated
1889             content=U
1890             if test -s $root_files \
1891                     -o -s $pp_wrkdir/%pre.$cmp \
1892                     -o -s $pp_wrkdir/%post.$cmp \
1893                     -o -s $pp_wrkdir/%preun.$cmp \
1894                     -o -s $pp_wrkdir/%check.$cmp
1895             then
1896                 content=B
1897             fi
1898
1899             if $pp_opt_debug; then
1900                 echo "$cmp USER %files:"
1901                 cat $user_files
1902                 echo "$cmp ROOT %files:"
1903                 cat $root_files
1904             fi >&2
1905
1906             bosboot=N; pp_contains_any "$pp_aix_bosboot" $cmp && bosboot=b
1907
1908             echo $pp_aix_bff_name.$ex \
1909                  ${pp_aix_version:-`pp_aix_version_fix "$version"`} \
1910                  1 $bosboot $content \
1911                  $pp_aix_lang "$summary $briefex"
1912             echo "["
1913
1914             pp_aix_depend $pp_wrkdir/%depend.$cmp
1915
1916             echo "%"
1917
1918             # generate per-directory size information
1919             pp_aix_size < $user_files
1920             pp_aix_size $instroot < $root_files
1921
1922             pp_aix_list            < $user_files  > $user_wrkdir/$pp_aix_bff_name.$ex.al
1923             pp_aix_list $instroot  < $root_files >> $user_wrkdir/$pp_aix_bff_name.$ex.al
1924             pp_aix_list            < $root_files  > $root_wrkdir/$pp_aix_bff_name.$ex.al
1925
1926             if $pp_opt_debug; then
1927                 echo "$cmp USER $pp_aix_bff_name.$ex.al:"
1928                 cat $user_wrkdir/$pp_aix_bff_name.$ex.al
1929                 echo "$cmp ROOT $pp_aix_bff_name.$ex.al:"
1930                 cat $root_wrkdir/$pp_aix_bff_name.$ex.al
1931             fi >&2
1932
1933             pp_aix_inventory $pp_aix_bff_name.$ex < $user_files \
1934                                        > $user_wrkdir/$pp_aix_bff_name.$ex.inventory
1935             pp_aix_inventory $pp_aix_bff_name.$ex < $root_files \
1936                                        > $root_wrkdir/$pp_aix_bff_name.$ex.inventory
1937
1938             if $pp_opt_debug; then
1939                 pp_debug "$cmp USER $pp_aix_bff_name.$ex.inventory:"
1940                 cat $user_wrkdir/$pp_aix_bff_name.$ex.inventory
1941                 pp_debug "$cmp ROOT $pp_aix_bff_name.$ex.inventory:"
1942                 cat $root_wrkdir/$pp_aix_bff_name.$ex.inventory
1943             fi >&2
1944
1945             if test x"" != x"${pp_aix_copyright:-$copyright}"; then
1946                 echo "${pp_aix_copyright:-$copyright}" > $user_wrkdir/$pp_aix_bff_name.$ex.copyright
1947                 echo "${pp_aix_copyright:-$copyright}" > $root_wrkdir/$pp_aix_bff_name.$ex.copyright
1948             fi
1949
1950             #-- assume that post/pre uninstall scripts only make
1951             #   sense when installed in a root context
1952
1953             if test -r $pp_wrkdir/%pre.$cmp; then
1954                         pp_aix_make_script $user_wrkdir/$pp_aix_bff_name.$ex.pre_i \
1955                 < $pp_wrkdir/%pre.$cmp
1956             fi
1957
1958             if test -r $pp_wrkdir/%post.$cmp; then
1959                 pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.post_i \
1960                         < $pp_wrkdir/%post.$cmp
1961             fi
1962
1963             if test -r $pp_wrkdir/%preun.$cmp; then
1964                 pp_aix_make_script $root_wrkdir/$pp_aix_bff_name.$ex.unpost_i \
1965                         < $pp_wrkdir/%preun.$cmp
1966             fi
1967
1968             # remove empty files
1969             for f in $user_wrkdir/$pp_aix_bff_name.$ex.* $root_wrkdir/$pp_aix_bff_name.$ex.*; do
1970               if test ! -s "$f"; then
1971                 pp_debug "removing empty $f"
1972                 rm -f "$f"
1973               fi
1974             done
1975
1976             # copy/link the root files so we can do an easy backup later
1977             pp_aix_copy_root $instroot < $root_files
1978
1979             echo "%"
1980             echo "]"
1981           done
1982           echo "}"
1983         } > $pp_wrkdir/lpp_name
1984
1985         if $pp_opt_debug; then
1986             echo "/lpp_name :"
1987             cat $pp_wrkdir/lpp_name
1988         fi >&2
1989
1990         #-- copy the /lpp_name file to the destdir
1991         pp_add_transient_file /lpp_name
1992         cp $pp_wrkdir/lpp_name $pp_destdir/lpp_name
1993
1994         #-- copy the liblpp.a files under destdir for packaging
1995         (cd $user_wrkdir && pp_verbose  ar -c -g -r liblpp.a $name.*) ||
1996                 pp_error "ar error"
1997         if test -s $user_wrkdir/liblpp.a; then
1998            pp_add_transient_file $instuser/liblpp.a
1999            pp_verbose cp $user_wrkdir/liblpp.a $pp_destdir$instuser/liblpp.a ||
2000                 pp_error "cannot create user liblpp.a"
2001         fi
2002         (cd $root_wrkdir && pp_verbose  ar -c -g -r liblpp.a $name.*) ||
2003                 pp_error "ar error"
2004         if test -s $root_wrkdir/liblpp.a; then
2005            pp_add_transient_file $instroot/liblpp.a
2006            pp_verbose cp $root_wrkdir/liblpp.a $pp_destdir$instroot/liblpp.a ||
2007                 pp_error "cannot create root liblpp.a"
2008         fi
2009
2010         { echo ./lpp_name
2011           test -s $user_wrkdir/liblpp.a && echo .$instuser/liblpp.a
2012           test -s $root_wrkdir/liblpp.a && echo .$instroot/liblpp.a
2013           cat $user_wrkdir/$name.*.al   # includes the relocated root files!
2014         } > $pp_wrkdir/bff.list
2015
2016         if test -n "$pp_aix_abis_seen" -a x"$pp_aix_arch_std" = x"auto"; then
2017             case "$pp_aix_abis_seen" in
2018                 "ppc ppc64"|"ppc64 ppc")
2019                     pp_aix_arch_std=ppc64
2020                     ;;
2021                 ppc|ppc64)
2022                     pp_aix_arch_std=$pp_aix_abis_seen
2023                     ;;
2024                 *" "*)
2025                     pp_warn "multiple architectures detected: $pp_aix_abis_seen"
2026                     pp_aix_arch_std=unknown
2027                     ;;
2028                 "")
2029                     pp_warn "no binary executables detected; using noarch"
2030                     pp_aix_arch_std=noarch
2031                     ;;
2032                 *)
2033                     pp_warn "unknown architecture detected $pp_aix_abis_seen"
2034                     pp_aix_arch_std=$pp_aix_abis_seen
2035                     ;;
2036             esac
2037         fi
2038
2039         . $pp_wrkdir/%fixup
2040
2041         outbff=`pp_backend_aix_names`
2042         pp_debug "creating: $pp_wrkdir/$outbff"
2043         (cd $pp_destdir && pp_verbose  /usr/sbin/backup -i -q -p -f -) \
2044           < $pp_wrkdir/bff.list \
2045           > $pp_wrkdir/$outbff || pp_error "backup failed"
2046         ${SUDO:-sudo} /usr/sbin/installp -l -d $pp_wrkdir/$outbff
2047 }
2048
2049 pp_backend_aix_cleanup () {
2050     :
2051 }
2052
2053 pp_backend_aix_names () {
2054         echo "$name.${pp_aix_version:-`pp_aix_version_fix "$version"`}.bff"
2055 }
2056
2057 pp_backend_aix_install_script () {
2058         typeset pkgname platform
2059         #
2060         # The script should take a first argument being the
2061         # operation; further arguments refer to components or services
2062         #
2063         # list-components           -- lists components in the pkg
2064         # install component...      -- installs the components
2065         # uninstall component...    -- uninstalles the components
2066         # list-services             -- lists the services in the pkg
2067         # start service...          -- starts the name service
2068         # stop service...           -- stops the named services
2069         # print-platform            -- prints the platform group
2070         #
2071         pkgname="`pp_backend_aix_names`"
2072         platform="`pp_backend_aix_probe`"   # XXX should be derived from files
2073
2074         fsets=
2075         for cmp in $pp_components; do
2076             case "$cmp" in
2077                 run) ex=rte;;
2078                 doc) ex=doc;;
2079                 dev) ex=adt;;
2080                 dbg) ex=diag;;
2081             esac
2082             fsets="$fsets $name.$ex"
2083         done
2084
2085         echo '#!/bin/sh'
2086         pp_install_script_common
2087
2088         cat <<-.
2089
2090             cpt_to_fileset () {
2091                 test x"\$*" = x"all" &&
2092                     set -- $pp_components
2093                 for cpt
2094                 do
2095                     case "\$cpt" in
2096                         run) echo "$name.rte";;
2097                         doc) echo "$name.doc";;
2098                         dev) echo "$name.adt";;
2099                         dbg) echo "$name.diag";;
2100                         *) usage;;
2101                     esac
2102                 done
2103             }
2104
2105             test \$# -eq 0 && usage
2106             op="\$1"; shift
2107
2108             case "\$op" in
2109                 list-components)
2110                     test \$# -eq 0 || usage \$op
2111                     echo "$pp_components"
2112                     ;;
2113                 list-services)
2114                     test \$# -eq 0 || usage \$op
2115                     echo "$pp_services"
2116                     ;;
2117                 list-files)
2118                     test \$# -ge 1 || usage \$op
2119                     echo \${PP_PKGDESTDIR:-.}/$pkgname
2120                     ;;
2121                 install)
2122                     test \$# -ge 1 || usage \$op
2123                     verbose /usr/sbin/installp -acX -V0 -F \
2124                         -d \${PP_PKGDESTDIR:-.}/$pkgname \
2125                         \`cpt_to_fileset "\$@"\`
2126                     ;;
2127                 uninstall)
2128                     test \$# -ge 1 || usage \$op
2129                     verbose /usr/sbin/installp -u -e/dev/null \
2130                         -V0 \`cpt_to_fileset "\$@"\`
2131                     ;;
2132                 start|stop)
2133                     test \$# -ge 1 || usage \$op
2134                     ec=0
2135                     for svc
2136                     do
2137                         verbose \${op}src -s \$svc || ec=1
2138                     done
2139                     exit \$ec
2140                     ;;
2141                 print-platform)
2142                     echo "$platform"
2143                     ;;
2144                 *)
2145                     usage;;
2146             esac
2147 .
2148 }
2149
2150 pp_backend_aix_init_svc_vars () {
2151     :
2152 }
2153
2154 pp_backend_aix_probe () {
2155         echo "${pp_aix_os}-${pp_aix_arch_std}"
2156 }
2157
2158 pp_backend_aix_vas_platforms () {
2159     case "${pp_aix_arch_std}" in
2160         ppc*)   :;;
2161         *)      pp_die "unknown architecture ${pp_aix_arch_std}";;
2162     esac
2163     case "${pp_aix_os}" in
2164         aix43)  echo "aix-43";;
2165         aix51)  echo "aix-51 aix-43";;
2166         aix52)  echo "aix-51 aix-43";;
2167         aix53)  echo "aix-53 aix-51 aix-43";;
2168         aix61)  echo "aix-53 aix-51 aix-43";;
2169         *)      pp_die "unknown system ${pp_aix_os}";;
2170     esac
2171 }
2172 pp_backend_aix_function () {
2173     case $1 in
2174     pp_mkgroup) cat <<'.';;
2175             /usr/sbin/lsgroup "$1" >/dev/null &&
2176                 return 0
2177             echo "Creating group $1"
2178             /usr/bin/mkgroup -A "$1"
2179 .
2180     pp_mkuser:depends) echo pp_mkgroup;;
2181     pp_mkuser) cat <<'.';;
2182             /usr/sbin/lsuser "$1" >/dev/null &&
2183                 return 0
2184             pp_mkgroup "${2:-$1}" || return 1
2185             echo "Creating user $1"
2186             /usr/bin/mkuser \
2187                 login=false \
2188                 rlogin=false \
2189                 account_locked=true \
2190                 home="${3:-/nohome.$1}" \
2191                 pgrp="${2:-$1}" \
2192                 "$1"
2193 .
2194     pp_havelib) cat <<'.';;
2195             case "$2" in
2196                 "")    pp_tmp_name="lib$1.so";;
2197                 *.*.*) pp_tmp_name="lib$1.so.$2";;
2198                 *.*)   pp_tmp_name="lib$1.so.$2.0";;
2199                 *)     pp_tmp_name="lib$1.so.$2";;
2200             esac
2201             for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
2202                 test -r "$pp_tmp_dir/$pp_tmp_name" -a \
2203                     -r "$pp_tmp_dir/lib$1.so" && return 0
2204             done
2205             return 1
2206 .
2207     *) false;;
2208     esac
2209 }
2210
2211 pp_platforms="$pp_platforms sd"
2212
2213 pp_backend_sd_detect () {
2214     test x"$1" = x"HP-UX"
2215 }
2216
2217 pp_backend_sd_init () {
2218     pp_sd_sudo=
2219     pp_sd_startlevels=2
2220     pp_sd_stoplevels=auto
2221     pp_sd_config_file=
2222     pp_sd_vendor=
2223     pp_sd_vendor_tag=Quest
2224     pp_sd_default_start=1           # config_file default start value
2225
2226     pp_readlink_fn=pp_ls_readlink   # HPUX has no readlink
2227
2228     pp_sd_detect_os
2229 }
2230
2231 pp_sd_detect_os () {
2232     typeset revision
2233
2234     revision=`uname -r`
2235     pp_sd_os="${revision#?.}"
2236     test -z "$pp_sd_os" &&
2237         pp_warn "cannot detect OS version"
2238     pp_sd_os_std="hpux`echo $pp_sd_os | tr -d .`"
2239
2240     case "`uname -m`" in
2241         9000/[678]??) pp_sd_arch_std=hppa;;
2242         ia64) pp_sd_arch_std=ia64;;
2243         *) pp_sd_arch_std=unknown;;
2244     esac
2245 }
2246
2247 pp_sd_write_files () {
2248     typeset t m o g f p st line dm
2249     while read t m o g f p st; do
2250         line="                file"
2251         case "$f" in *v*) line="$line -v";; esac    # FIXME for uninstall
2252         case $t in
2253             f) dm=644;;
2254             d) line="$line -t d"; p=${p%/}; dm=755;;
2255             s) line="$line -t s";;
2256         esac
2257
2258         test x"$o" = x"-" && o=root
2259         test x"$g" = x"-" && g=sys
2260         test x"$m" = x"-" && m=$dm
2261
2262         case $t in
2263             s) echo "$line $st $p";;
2264             *) echo "$line -o $o -g $g -m $m $pp_destdir$p $p";;
2265         esac
2266
2267     done
2268 }
2269
2270 pp_sd_service_group_script () {
2271     typeset grp svcs scriptpath out
2272     grp="$1"
2273     svcs="$2"
2274     scriptpath="/sbin/init.d/$grp"
2275     out="$pp_destdir$scriptpath"
2276
2277     pp_add_file_if_missing $scriptpath run 755 || return 0
2278
2279     cat <<-. > $out
2280         #!/sbin/sh
2281         # generated by pp $pp_version
2282         svcs="$svcs"
2283 .
2284
2285     cat <<-'.' >> $out
2286         #-- starts services in order.. stops them all if any break
2287         pp_start () {
2288             undo=
2289             for svc in $svcs; do
2290                 /sbin/init.d/$svc start
2291                 case $? in
2292                   0|4)
2293                     undo="$svc $undo"
2294                     ;;
2295                   *)
2296                     if test -n "$undo"; then
2297                         for svc in $undo; do
2298                            /sbin/init.d/$svc stop
2299                         done
2300                         return 1
2301                     fi
2302                     ;;
2303                 esac
2304             done
2305             return 0
2306         }
2307
2308         #-- stops services in reverse
2309         pp_stop () {
2310             reverse=
2311             for svc in $svcs; do
2312                 reverse="$svc $reverse"
2313             done
2314             rc=0
2315             for svc in $reverse; do
2316                 /sbin/init.d/$svc stop || rc=$?
2317             done
2318             return $rc
2319         }
2320
2321         case $1 in
2322             start_msg) echo "Starting $svcs";;
2323             stop_msg)  echo "Stopping $svcs";;
2324             start)     pp_start;;
2325             stop)      pp_stop;;
2326             *)         echo "usage: $0 {start|stop|start_msg|stop_msg}"
2327                        exit 1;;
2328         esac
2329 .
2330 }
2331
2332 pp_sd_service_script () {
2333     typeset svc config_file config_value scriptpath out
2334
2335     svc="$1"
2336     scriptpath="/sbin/init.d/$svc"
2337
2338     config_file=${pp_sd_config_file:-/etc/rc.config.d/$svc}
2339     sd_config_var=`echo run-$svc | tr '[a-z]-' '[A-Z]_'`
2340     sd_config_value=${pp_sd_default_start:-0}
2341     pp_load_service_vars "$svc"
2342
2343     test -n "$user" -a x"$user" != x"root" &&
2344         cmd="SHELL=/usr/bin/sh /usr/bin/su $user -c \"exec `echo $cmd | sed -e 's,[$\\\`],\\&,g'`\""
2345     if test -z "$pidfile"; then
2346         pidfile="/var/run/$svc.pid"
2347         cmd="$cmd & echo \$! > \$pidfile"
2348     fi
2349
2350     pp_debug "config file is $config_file"
2351
2352     pp_add_file_if_missing $scriptpath run 755
2353     pp_add_file_if_missing $config_file run 644 v
2354
2355     cat <<-. >> $pp_destdir$config_file
2356
2357         # Controls whether the $svc service is started
2358         $sd_config_var=$sd_config_value
2359 .
2360
2361     if test ! -f $pp_destdir$scriptpath; then
2362     cat <<-. > $pp_destdir$scriptpath
2363         #!/sbin/sh
2364         # generated by pp $pp_version
2365
2366         svc="$svc"
2367         pidfile="$pidfile"
2368         config_file="$config_file"
2369
2370         pp_start () {
2371             $cmd
2372         }
2373
2374         pp_disabled () {
2375             test \${$sd_config_var:-0} -eq 0
2376         }
2377
2378         pp_stop () {
2379             if test ! -s "$pidfile"; then
2380                 echo "Unable to stop $svc (no pid file)"
2381                 return 1
2382             else
2383                 read pid < "$pidfile"
2384                 if kill -0 "$pid" 2>/dev/null; then
2385                     if kill -${stop_signal:-TERM} "$pid"; then
2386                         rm -f "$pidfile"
2387                         return 0
2388                     else
2389                         echo "Unable to stop $svc"
2390                         return 1
2391                     fi
2392                 else
2393                     rm -f "$pidfile"
2394                     return 0
2395                 fi
2396             fi
2397         }
2398
2399         pp_running () {
2400             if test ! -s "$pidfile"; then
2401                 return 1
2402             else
2403                 read pid < "$pidfile"
2404                 kill -0 "$pid" 2>/dev/null
2405             fi
2406         }
2407
2408         case $1 in
2409             start_msg) echo "Starting the $svc service";;
2410             stop_msg)  echo "Stopping the $svc service";;
2411             start)
2412                     if test -f "$config_file"; then
2413                         . $config_file
2414                     fi
2415                     if pp_disabled; then
2416                         exit 2
2417                     elif pp_running; then
2418                         echo "$svc already running";
2419                         exit 0
2420                     elif pp_start; then
2421                         echo "$svc started";
2422                         # rc(1M) says we should exit 4, but nobody expects it!
2423                         exit 0
2424                     else
2425                         exit 1
2426                     fi;;
2427             stop)   if pp_stop; then
2428                         echo "$svc stopped";
2429                         exit 0
2430                     else
2431                         exit 1
2432                     fi;;
2433             *) echo "usage: $0 {start|stop|start_msg|stop_msg}"
2434                exit 1;;
2435         esac
2436 .
2437     fi
2438 }
2439
2440 pp_sd_make_service () {
2441         typeset level startpriority stoppriority startlevels stoplevels
2442         typeset svc svcvar
2443
2444         svc="$1"
2445         svcvar=`pp_makevar $svc`
2446
2447         # TODO: Figure out why this check is here
2448         #-- don't do anything if the script exists
2449         #if test -s "$pp_destdir/sbin/init.d/$svc"; then
2450         #    pp_error "$pp_destdir/sbin/init.d/$svc exists"
2451         #    return
2452         #fi
2453
2454         # symlink the script, depending on the priorities chosen
2455         eval startpriority='${pp_sd_startpriority_'$svcvar'}'
2456         eval stoppriority='${pp_sd_stoppriority_'$svcvar'}'
2457         test -z "$startpriority" && startpriority="${pp_sd_startpriority:-50}"
2458         test -z "$stoppriority" && stoppriority="${pp_sd_stoppriority:-50}"
2459
2460         eval startlevels='${pp_sd_startlevels_'$svcvar'}'
2461         test -z "$startlevels" && startlevels="$pp_sd_startlevels"
2462
2463         eval stoplevels='${pp_sd_stoplevels_'$svcvar'}'
2464         test -z "$stoplevels" && stoplevels="$pp_sd_stoplevels"
2465
2466         # create the script and config file
2467         pp_sd_service_script $svc
2468
2469         # fix the priority up
2470         case "$startpriority" in
2471             ???) :;;
2472             ??) startpriority=0$startpriority;;
2473             ?) startpriority=00$startpriority;;
2474         esac
2475         case "$stoppriority" in
2476             ???) :;;
2477             ??) stoppriority=0$stoppriority;;
2478             ?) stoppriority=00$stoppriority;;
2479         esac
2480
2481         if test x"$stoplevels" = x"auto"; then
2482             stoplevels=
2483             test -z "$startlevels" || for level in $startlevels; do
2484                 stoplevels="$stoplevels `expr $level - 1`"
2485             done
2486         fi
2487
2488         # create the symlinks
2489         test -z "$startlevels" || for level in $startlevels; do
2490             echo "                file -t s" \
2491                     "/sbin/init.d/$svc" \
2492                     "/sbin/rc$level.d/S$startpriority$svc"
2493         done
2494         test -z "$stoplevels" || for level in $stoplevels; do
2495             echo "                file -t s" \
2496                     "/sbin/init.d/$svc" \
2497                     "/sbin/rc$level.d/K$stoppriority$svc"
2498         done
2499 }
2500
2501 pp_sd_control () {
2502     typeset ctrl script
2503     typeset cpt
2504
2505     ctrl="$1"; shift
2506     cpt="$1"; shift
2507     script="$pp_wrkdir/control.$ctrl.$cpt"
2508     cat <<. >$script
2509 .
2510     cat "$@" >> $script
2511     echo "exit 0" >> $script
2512     /usr/bin/chmod +x $script
2513     echo "                $ctrl $script"
2514 }
2515
2516 pp_backend_sd () {
2517     typeset psf cpt svc outfile
2518
2519     psf=$pp_wrkdir/psf
2520
2521     echo "depot" > $psf
2522     echo "layout_version 1.0" >>$psf
2523
2524     #-- vendor
2525     cat <<. >>$psf
2526         vendor
2527             tag             $pp_sd_vendor_tag
2528             title           "${pp_sd_vendor:-$vendor}"
2529         end
2530
2531         product
2532             tag             $name
2533             revision        $version
2534             vendor_tag      $pp_sd_vendor_tag
2535             is_patch        false
2536             title           "$summary"
2537             copyright       "$copyright"
2538             machine_type    *
2539             os_name         HP-UX
2540             os_release      ?.11.*
2541             os_version      ?
2542             directory       /
2543             is_locatable    false
2544 .
2545     test -n "$description" \
2546         && echo $description > $pp_wrkdir/description \
2547         && cat <<. >> $psf
2548             description     < $pp_wrkdir/description
2549 .
2550
2551     # make convenience service groups
2552     if test -n "$pp_service_groups"; then
2553         for grp in $pp_service_groups; do
2554             pp_sd_service_group_script \
2555                 $grp "`pp_service_get_svc_group $grp`"
2556         done
2557     fi
2558
2559     for cpt in $pp_components; do
2560         cat <<. >>$psf
2561             fileset
2562                 tag             ${pp_sd_fileset_tag:-$cpt}
2563                 title           "${summary:-cpt}"
2564                 revision        $version
2565 .
2566
2567         #-- make sure services are shut down during uninstall
2568         if test $cpt = run -a -n "$pp_services"; then
2569             for svc in $pp_services; do
2570                 pp_prepend $pp_wrkdir/%preun.$cpt <<-.
2571                         /sbin/init.d/$svc stop
2572 .
2573             done
2574         fi
2575
2576         #-- we put the post/preun code into configure/unconfigure
2577         # and not postinstall/preremove, because configure/unconfigure
2578         # scripts are run on the hosts where the package is installed,
2579         # not loaded (a subtle difference).
2580         test -s $pp_wrkdir/%pre.$cpt &&
2581             pp_sd_control checkinstall $cpt $pp_wrkdir/%pre.$cpt >> $psf
2582         test -s $pp_wrkdir/%post.$cpt &&
2583             pp_sd_control configure $cpt $pp_wrkdir/%post.$cpt >> $psf
2584         test -s $pp_wrkdir/%preun.$cpt &&
2585             pp_sd_control unconfigure $cpt $pp_wrkdir/%preun.$cpt >> $psf
2586         test -s $pp_wrkdir/%postun.$cpt &&
2587             pp_sd_control postremove $cpt $pp_wrkdir/%postun.$cpt >> $psf
2588         test -s $pp_wrkdir/%check.$cpt &&
2589             pp_sd_control checkinstall $cpt $pp_wrkdir/%check.$cpt >> $psf
2590
2591         if test $cpt = run -a -n "$pp_services"; then
2592             for svc in $pp_services; do
2593                 #-- service names are 10 chars max on hpux
2594                 case "$svc" in ???????????*)
2595                     pp_warn "service name '$svc' is too long for hpux";;
2596                 esac
2597                 pp_sd_make_service $svc >> $psf
2598             done
2599             #pp_sd_make_service_config
2600         fi
2601
2602         pp_sd_write_files < $pp_wrkdir/%files.$cpt >> $psf
2603
2604         #-- end fileset clause
2605         cat <<. >>$psf
2606             end
2607 .
2608
2609     done
2610
2611     #-- end product clause
2612     cat <<. >>$psf
2613         end
2614 .
2615
2616     $pp_opt_debug && cat $psf >&2
2617
2618     test -s $pp_wrkdir/%fixup && . $pp_wrkdir/%fixup
2619
2620     outfile=`pp_backend_sd_names`
2621     if pp_verbose ${pp_sd_sudo} /usr/sbin/swpackage \
2622         -s $psf \
2623         -x run_as_superuser=false \
2624         -x media_type=tape \
2625         @ $pp_wrkdir/$outfile
2626     then
2627         pp_verbose ${pp_sd_sudo} /usr/sbin/swlist -l file -s $pp_wrkdir/$outfile
2628     else
2629         pp_error "swpackage failed"
2630     fi
2631 }
2632
2633 pp_backend_sd_cleanup () {
2634     :
2635 }
2636
2637 pp_backend_sd_names () {
2638     echo "$name-$version.$pp_sd_arch_std.depot"
2639 }
2640
2641 pp_backend_sd_install_script () {
2642     typeset pkgname platform
2643
2644     pkgname=`pp_backend_sd_names`
2645     platform="`pp_backend_sd_probe`"
2646
2647     echo "#!/bin/sh"
2648     pp_install_script_common
2649     cat <<.
2650
2651         cpt_to_tags () {
2652             test x"\$*" = x"all" && set -- $pp_components
2653             for cpt
2654             do
2655                 echo "$name.\$cpt"
2656             done
2657         }
2658
2659         test \$# -eq 0 && usage
2660         op="\$1"; shift
2661
2662         case "\$op" in
2663             list-components)
2664                 test \$# -eq 0 || usage \$op
2665                 echo "$pp_components"
2666                 ;;
2667             list-services)
2668                 test \$# -eq 0 || usage \$op
2669                 echo "$pp_services"
2670                 ;;
2671             list-files)
2672                 test \$# -ge 1 || usage \$op
2673                 echo \${PP_PKGDESTDIR:-.}/$pkgname
2674                 ;;
2675             install)
2676                 test \$# -ge 1 || usage \$op
2677                 verbose /usr/sbin/swinstall -x verbose=0 \
2678                     -s \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \
2679                     \`cpt_to_tags "\$@"\`
2680                 ;;
2681             uninstall)
2682                 test \$# -ge 1 || usage \$op
2683                 verbose /usr/sbin/swremove -x verbose=0 \
2684                     \`cpt_to_tags "\$@"\`
2685                 ;;
2686             start|stop)
2687                 test \$# -ge 1 || usage \$op
2688                 ec=0
2689                 for svc
2690                 do
2691                     verbose /sbin/init.d/\$svc \$op
2692                     [ \$? -eq 4 -o \$? -eq 0 ] || ec=1
2693                 done
2694                 exit \$ec
2695                 ;;
2696             print-platform)
2697                 echo "$platform"
2698                 ;;
2699             *)
2700                 usage
2701                 ;;
2702         esac
2703 .
2704 }
2705
2706 pp_backend_sd_probe () {
2707     echo "${pp_sd_os_std}-${pp_sd_arch_std}"
2708 }
2709
2710 pp_backend_sd_vas_platforms () {
2711     case "`pp_backend_sd_probe`" in
2712         hpux*-hppa) echo hpux-pa;;
2713         hpux*-ia64) echo hpux-ia64 hpux-pa;;
2714         *)          pp_die "unknown system `pp_backend_sd_probe`";;
2715     esac
2716 }
2717
2718 pp_backend_sd_init_svc_vars () {
2719     :
2720 }
2721 pp_backend_sd_function () {
2722     case $1 in
2723         pp_mkgroup) cat <<'.';;
2724             /usr/sbin/groupmod "$1" 2>/dev/null ||
2725                 /usr/sbin/groupadd "$1"
2726 .
2727         pp_mkuser:depends) echo pp_mkgroup;;
2728         pp_mkuser) cat <<'.';;
2729             pp_mkgroup "${2:-$1}" || return 1
2730             /usr/sbin/useradd \
2731                 -g "${2:-$1}" \
2732                 -d "${3:-/nonexistent}" \
2733                 -s "${4:-/bin/false}" \
2734                 "$1"
2735 .
2736         pp_havelib) cat <<'.';;
2737             for pp_tmp_dir in `echo /usr/lib${3:+:$3} | tr : ' '`; do
2738                 test -r "$pp_tmp_dir/lib$1${2:+.$2}.sl" && return 0
2739             done
2740             return 1
2741 .
2742         *) false;;
2743     esac
2744 }
2745
2746 pp_platforms="$pp_platforms solaris"
2747
2748 pp_backend_solaris_detect () {
2749         test x"$1" = x"SunOS"
2750 }
2751
2752 pp_backend_solaris_init () {
2753         pp_solaris_category=
2754         pp_solaris_istates="s S 1 2 3"  # run-states when install is ok
2755         pp_solaris_rstates="s S 1 2 3"  # run-states when remove is ok
2756         pp_solaris_vendor=
2757         pp_solaris_copyright=
2758         pp_solaris_name=
2759         pp_solaris_desc=
2760         pp_solaris_package_arch=auto
2761
2762         pp_solaris_detect_os
2763         pp_solaris_detect_arch
2764
2765         pp_solaris_init_svc
2766
2767         #-- readlink not reliably available on Solaris
2768         pp_readlink_fn=pp_ls_readlink
2769 }
2770
2771 pp_solaris_detect_os () {
2772         typeset osrel
2773
2774         osrel=`/usr/bin/uname -r`
2775         case "$osrel" in
2776             5.[0-6])    pp_solaris_os="sol2${osrel#5.}";;
2777             5.*)        pp_solaris_os="sol${osrel#5.}";;
2778         esac
2779         test -z "$pp_solaris_os" &&
2780              pp_warn "can't determine OS suffix from uname -r"
2781
2782 }
2783
2784 pp_solaris_detect_arch () {
2785         pp_solaris_arch=`/usr/bin/optisa amd64 sparcv9 i386 sparc`
2786         [ -z "$pp_solaris_arch" ] &&
2787             pp_error "can't determine processor architecture"
2788         case "$pp_solaris_arch" in
2789             amd64)   pp_solaris_arch_std=x86_64;;
2790             i386)    pp_solaris_arch_std=i386;;
2791             sparcv9) pp_solaris_arch_std=sparc64;;
2792             sparc)   pp_solaris_arch_std=sparc;;
2793             *)       pp_solaris_arch_std=unknown;;
2794         esac
2795 }
2796
2797 pp_solaris_is_request_script_necessary () {
2798     typeset has_optional_services
2799
2800     has_optional_services=no
2801     for _svc in $pp_services; do
2802         pp_load_service_vars $_svc
2803         if test "$optional" = "yes"; then
2804             has_optional_services=yes
2805         fi
2806     done
2807
2808     # If the package has no optional services and only one component, don't
2809     # create a request script at all.
2810     if test "$has_optional_services" = "no" &&
2811        test `echo $pp_components | wc -w` -eq 1; then
2812         return 1 # no
2813     fi
2814
2815     return 0 # yes
2816 }
2817
2818 pp_solaris_request () {
2819     typeset _cmp _svc
2820
2821     #-- The common part of the request script contains the ask() function
2822     #   and resets the CLASSES list to empty
2823     cat <<'.'
2824         trap 'exit 3' 15
2825         ask () {
2826            ans=`ckyorn -d "$1" \
2827                 -p "Do you want to $2"` \
2828             || exit $?
2829            case "$ans" in y*|Y*) return 0;; *) return 1;; esac
2830         }
2831         CLASSES=
2832 .
2833     #-- each of our components adds itself to the CLASSES list
2834     for _cmp in $pp_components; do
2835       case "$_cmp" in
2836             run) :;;
2837             doc) echo 'ask y "install the documentation files" &&';;
2838             dev) echo 'ask y "install the development files" &&';;
2839             dbg) echo 'ask n "install the diagnostic files" &&';;
2840       esac
2841       echo '    CLASSES="$CLASSES '$_cmp'"'
2842     done
2843
2844     #-- the request script writes the CLASSES var to its output
2845     cat <<'.'
2846         echo "CLASSES=$CLASSES" > $1
2847 .
2848
2849     if test -n "$pp_services"; then
2850         echo 'SERVICES='
2851         for _svc in $pp_services; do
2852             pp_load_service_vars $_svc
2853             if test "$enable" = "yes"; then
2854                 _default_prompt=y
2855             else
2856                 _default_prompt=n
2857             fi
2858             if test "$optional" = "yes"; then
2859                 echo 'ask '$_default_prompt' "install '$_svc' service" &&'
2860             fi
2861             echo '    SERVICES="$SERVICES '$_svc'"'
2862         done
2863         echo 'echo "SERVICES=$SERVICES" >> $1'
2864     fi
2865
2866 }
2867
2868 pp_solaris_procedure () {
2869     cat <<.
2870
2871         #-- $2 for $1 component of $name
2872         case " \$CLASSES " in *" $1 "*)
2873 .
2874     cat
2875     cat <<.
2876         ;; esac
2877 .
2878 }
2879
2880 pp_solaris_depend () {
2881     typeset _name _vers
2882     while read _name _vers; do
2883         if test -n "$_name"; then
2884             echo "P $_name $_name"
2885             test -n "$_vers" && echo " $_vers"
2886         fi
2887     done
2888 }
2889
2890 pp_solaris_space() {
2891     echo "$2:$3:$1" >> $pp_wrkdir/space.cumulative
2892 }
2893
2894 pp_solaris_sum_space () {
2895     if test -s $pp_wrkdir/space.cumulative; then
2896         sort -t: +2 < $pp_wrkdir/space.cumulative |
2897         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
2898     fi
2899 }
2900
2901 pp_solaris_proto () {
2902         typeset t m o g f p st
2903         typeset abi
2904
2905         while read t m o g f p st; do
2906           if test x"$o" = x"-"; then
2907             o="root"
2908           fi
2909           if test x"$g" = x"-"; then
2910             g="bin"
2911           fi
2912           case "$t" in
2913             f) test x"$m" = x"-" && m=444
2914                case "$f" in
2915                 *v*) echo "v $1 $p=$pp_destdir$p $m $o $g";;
2916                 *)   echo "f $1 $p=$pp_destdir$p $m $o $g";;
2917                esac
2918                if test -r "$pp_destdir$p"; then
2919                   #-- Use file to record ABI types seen
2920                   case "`file "$pp_destdir$p"`" in
2921                     *"ELF 32"*80386*) abi=i386;;
2922                     *"ELF 64"*AMD*) abi=x86_64;;
2923                     *"ELF 32"*SPARC*) abi=sparc;;
2924                     *"ELF 64"*SPARC*) abi=sparc64;;
2925                     *) abi=;;
2926                   esac
2927                   if test -n "$abi"; then
2928                     pp_add_to_list pp_solaris_abis_seen $abi
2929                   fi
2930                fi
2931                ;;
2932             d) test x"$m" = x"-" && m=555
2933                echo "d $1 $p $m $o $g"
2934                ;;
2935             s) test x"$m" = x"-" && m=777
2936                test x"$m" = x"777" ||
2937                   pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
2938                echo "s $1 $p=$st $m $o $g"
2939                ;;
2940           esac
2941         done
2942 }
2943
2944 pp_backend_solaris () {
2945         typeset _cmp _svc _grp
2946
2947         prototype=$pp_wrkdir/prototype
2948         : > $prototype
2949
2950         pkginfo=$pp_wrkdir/pkginfo
2951         : > $pkginfo
2952         echo "i pkginfo=$pkginfo" >> $prototype
2953
2954         case "${pp_solaris_name:-$name}" in
2955             [0-9]*)
2956                 pp_error "Package name '${pp_solaris_name:-$name}'" \
2957                         "cannot start with a number"
2958                 ;;
2959             ???????????????*)
2960                 pp_warn "Package name '${pp_solaris_name:-$name}'" \
2961                         "too long for Solaris 2.6 or 2.7 (max 9 characters)"
2962                 ;;
2963             ??????????*)
2964                 pp_warn "Package name '${pp_solaris_name:-$name}'" \
2965                         "too long for 2.7 Solaris (max 9 characters)"
2966                 ;;
2967         esac
2968
2969         #-- generate the package info file
2970         echo "VERSION=$version" >> $pkginfo
2971         echo "PKG=${pp_solaris_name:-$name}" >> $pkginfo
2972         echo "CLASSES=$pp_components" >> $pkginfo
2973         echo "BASEDIR=/" >> $pkginfo
2974         echo "NAME=$name $version" >> $pkginfo
2975         echo "CATEGORY=${pp_solaris_category:-application}" >> $pkginfo
2976
2977         desc="${pp_solaris_desc:-$description}"
2978         test -n "$desc" &&
2979           echo "DESC=$desc" >> $pkginfo
2980
2981         test -n "$pp_solaris_rstates" &&
2982           echo "RSTATES=$pp_solaris_rstates" >> $pkginfo
2983         test -n "$pp_solaris_istates" &&
2984           echo "ISTATES=$pp_solaris_istates" >> $pkginfo
2985         test -n "${pp_solaris_vendor:-$vendor}" &&
2986           echo "VENDOR=${pp_solaris_vendor:-$vendor}" >> $pkginfo
2987
2988         if test -n "${pp_solaris_copyright:-$copyright}"; then
2989             echo "${pp_solaris_copyright:-$copyright}" > $pp_wrkdir/copyright
2990             echo "i copyright=$pp_wrkdir/copyright" >> $prototype
2991         fi
2992
2993         #-- scripts to run before and after install
2994         : > $pp_wrkdir/postinstall
2995         : > $pp_wrkdir/preremove
2996         for _cmp in $pp_components; do
2997         #-- add the preinstall scripts in definition order
2998         if test -s $pp_wrkdir/%pre.$_cmp; then
2999             pp_solaris_procedure $_cmp preinst < $pp_wrkdir/%pre.$_cmp \
3000                 >> $pp_wrkdir/preinstall
3001         fi
3002         #-- add the postinstall scripts in definition order
3003         if test -s $pp_wrkdir/%post.$_cmp; then
3004             pp_solaris_procedure $_cmp postinst < $pp_wrkdir/%post.$_cmp \
3005                 >> $pp_wrkdir/postinstall
3006         fi
3007         #-- add the preremove rules in reverse definition order
3008         if test -s $pp_wrkdir/%preun.$_cmp; then
3009             pp_solaris_procedure $_cmp preremove < $pp_wrkdir/%preun.$_cmp |
3010                     pp_prepend $pp_wrkdir/preremove
3011         fi
3012         #-- Add the check script in definition order
3013         if test -s $pp_wrkdir/%check.$_cmp; then
3014             pp_solaris_procedure $_cmp checkinstall \
3015                         < $pp_wrkdir/%check.$_cmp \
3016                         >> $pp_wrkdir/checkinstall
3017         fi
3018         #-- All dependencies are merged together for Solaris pkgs
3019         test -s $pp_wrkdir/%depend.$_cmp &&
3020               pp_solaris_depend < $pp_wrkdir/%depend.$_cmp > $pp_wrkdir/depend
3021         done
3022
3023
3024         if pp_solaris_is_request_script_necessary; then
3025             pp_solaris_request > $pp_wrkdir/request
3026         fi
3027
3028         test -n "$pp_services" &&
3029             for _svc in $pp_services; do
3030                 pp_load_service_vars $_svc
3031                 pp_solaris_make_service $_svc
3032                 pp_solaris_install_service $_svc | pp_prepend $pp_wrkdir/postinstall
3033                 pp_prepend $pp_wrkdir/preremove <<-.
3034                     /etc/init.d/$_svc stop >/dev/null 2>/dev/null
3035 .
3036             done
3037
3038         test -n "$pp_service_groups" &&
3039             for _grp in $pp_service_groups; do
3040                 pp_solaris_make_service_group \
3041                     $_grp "`pp_service_get_svc_group $_grp`"
3042             done
3043
3044         #-- if installf was used; we need to indicate a termination
3045         grep installf $pp_wrkdir/postinstall >/dev/null &&
3046             echo 'installf -f $PKGINST' >> $pp_wrkdir/postinstall
3047
3048         pp_solaris_sum_space
3049
3050         # NB: pkginfo and copyright are added earlier
3051         for f in compver depend space checkinstall \
3052                  preinstall request postinstall \
3053                  preremove postremove; do
3054             if test -s $pp_wrkdir/$f; then
3055                 case $f in
3056                     *install|*remove|request)
3057                         # turn scripts into a proper shell scripts
3058                         mv $pp_wrkdir/$f $pp_wrkdir/$f.tmp
3059                         { echo "#!/bin/sh";
3060                           echo "# $f script for ${pp_solaris_name:-$name}-$version"
3061                           cat $pp_wrkdir/$f.tmp
3062                           echo "exit 0"; } > $pp_wrkdir/$f
3063                         chmod +x $pp_wrkdir/$f
3064                         rm -f $pp_wrkdir/$f.tmp
3065                         ;;
3066                 esac
3067                 if $pp_opt_debug; then
3068                     pp_debug "contents of $f:"
3069                     cat $pp_wrkdir/$f >&2
3070                 fi
3071                 echo "i $f=$pp_wrkdir/$f" >> $prototype
3072             fi
3073         done
3074
3075         #-- create the prototype file which lists the files to install
3076         # do this as late as possible because files could be added
3077         pp_solaris_abis_seen=
3078         for _cmp in $pp_components; do
3079           pp_solaris_proto $_cmp < $pp_wrkdir/%files.$_cmp
3080         done >> $prototype
3081
3082         if test x"$pp_solaris_package_arch" = x"auto"; then
3083             if pp_contains "$pp_solaris_abis_seen" sparc64; then
3084                 pp_solaris_package_arch_std="sparc64"
3085                 echo "ARCH=sparcv9" >> $pkginfo
3086             elif pp_contains "$pp_solaris_abis_seen" sparc; then
3087                 pp_solaris_package_arch_std="sparc"
3088                 echo "ARCH=sparc" >> $pkginfo
3089             elif pp_contains "$pp_solaris_abis_seen" x86_64; then
3090                 pp_solaris_package_arch_std="x86_64"
3091                 echo "ARCH=amd64" >> $pkginfo
3092             elif pp_contains "$pp_solaris_abis_seen" i386; then
3093                 pp_solaris_package_arch_std="i386"
3094                 echo "ARCH=i386" >> $pkginfo
3095             else
3096                 pp_warn "No ELF files found: not supplying an ARCH type"
3097                 pp_solaris_package_arch_std="noarch"
3098             fi
3099         else
3100             pp_solaris_package_arch_std="$pp_solaris_package_arch"
3101             echo "ARCH=$pp_solaris_package_arch" >> $pkginfo
3102         fi
3103
3104         mkdir $pp_wrkdir/pkg
3105
3106         . $pp_wrkdir/%fixup
3107
3108 if $pp_opt_debug; then
3109   echo "$pkginfo::"; cat $pkginfo
3110   echo "$prototype::"; cat $prototype
3111 fi >&2
3112
3113         pkgmk -a $pp_solaris_arch -d $pp_wrkdir/pkg \
3114               -f $prototype || { error "pkgmk failed"; return; }
3115         pkgtrans -s $pp_wrkdir/pkg \
3116                 $pp_wrkdir/`pp_backend_solaris_names` \
3117                 ${pp_solaris_name:-$name} \
3118                 || { error "pkgtrans failed"; return; }
3119 }
3120
3121 pp_backend_solaris_cleanup () {
3122         :
3123 }
3124
3125 pp_backend_solaris_names () {
3126         echo ${pp_solaris_name:-$name}-$version-${pp_solaris_package_arch_std:-$pp_solaris_arch}.pkg
3127 }
3128
3129 pp_backend_solaris_install_script () {
3130         typeset pkgname platform
3131
3132         platform="${pp_solaris_os:-solaris}-${pp_solaris_package_arch_std:-$pp_solaris_arch}"
3133
3134         echo "#! /sbin/sh"
3135         pp_install_script_common
3136         pkgname=`pp_backend_solaris_names`
3137
3138         cat <<.
3139             tmpnocheck=/tmp/nocheck\$\$
3140             tmpresponse=/tmp/response\$\$
3141             trap 'rm -f \$tmpnocheck \$tmpresponse' 0
3142
3143             make_tmpfiles () {
3144                 cat <<-.. > \$tmpresponse
3145                         CLASSES=\$*
3146                         SERVICES=$pp_services
3147 ..
3148                 cat <<-.. > \$tmpnocheck
3149                         mail=
3150                         instance=overwrite
3151                         partial=nocheck
3152                         runlevel=nocheck
3153                         idepend=nocheck
3154                         rdepend=nocheck
3155                         space=nocheck
3156                         setuid=nocheck
3157                         conflict=nocheck
3158                         action=nocheck
3159                         basedir=default
3160 ..
3161             }
3162
3163             test \$# -eq 0 && usage
3164             op="\$1"; shift
3165
3166             case "\$op" in
3167                 list-components)
3168                     test \$# -eq 0 || usage \$op
3169                     echo "$pp_components"
3170                     ;;
3171                 list-services)
3172                     test \$# -eq 0 || usage \$op
3173                     echo "$pp_services"
3174                     ;;
3175                 list-files)
3176                     test \$# -ge 1 || usage \$op
3177                     echo \${PP_PKGDESTDIR:-.}/$pkgname
3178                     ;;
3179                 install)
3180                     test \$# -ge 1 || usage \$op
3181                     make_tmpfiles "\$@"
3182                     verbose /usr/sbin/pkgadd -n -d \${PP_PKGDESTDIR:-.}/$pkgname \
3183                         -r \$tmpresponse \
3184                         -a \$tmpnocheck \
3185                         ${pp_solaris_name:-$name}
3186                     ;;
3187                 uninstall)
3188                     test \$# -ge 1 || usage \$op
3189                     make_tmpfiles "\$@"
3190                     verbose /usr/sbin/pkgrm -n \
3191                         -a \$tmpnocheck \
3192                         ${pp_solaris_name:-$name}
3193                     ;;
3194                 start|stop)
3195                     test \$# -ge 1 || usage \$op
3196                     ec=0
3197                     for svc
3198                     do
3199                         verbose /etc/init.d/\$svc \$op || ec=1
3200                     done
3201                     exit \$ec
3202                     ;;
3203                 print-platform)
3204                     echo "$platform"
3205                     ;;
3206                 *)
3207                     usage
3208                     ;;
3209             esac
3210 .
3211 }
3212
3213 pp_solaris_dynlib_depend () {
3214         xargs ldd 2>/dev/null |
3215         sed -e '/^[^    ]*:$/d' -e 's,.*=>[      ]*,,' -e 's,^[         ]*,,' |
3216         sort -u |
3217         grep -v '^/usr/platform/' | (
3218           set -- ""; shift
3219           while read p; do
3220             set -- "$@" -p "$p"
3221             if [ $# -gt 32 ]; then
3222                 echo "$# is $#" >&2
3223                 pkgchk -l "$@"
3224                 set -- ""; shift
3225             fi
3226           done
3227           [ $# -gt 0 ] && pkgchk -l "$@"
3228         )|
3229         awk '/^Current status:/{p=0} p==1 {print $1} /^Referenced by/ {p=1}' |
3230         sort -u |
3231         xargs -l32 pkginfo -x |
3232         awk 'NR % 2 == 1 { name=$1; } NR%2 == 0 { print name, $2 }'
3233 }
3234
3235 pp_solaris_add_dynlib_depends () {
3236     typeset tmp
3237     tmp=$pp_wrkdir/tmp.dynlib
3238
3239     for _cmp in $pp_components; do
3240         awk '{print destdir $6}' destdir="$pp_destdir" \
3241                 < $pp_wrkdir/%files.$_cmp |
3242         pp_solaris_dynlib_depend > $tmp
3243         if test -s $tmp; then
3244             cat $tmp >> $pp_wrkdir/%depend.$_cmp
3245         fi
3246         rm -f $tmp
3247     done
3248 }
3249
3250 pp_backend_solaris_probe () {
3251     echo "${pp_solaris_os}-${pp_solaris_arch_std}"
3252 }
3253
3254 pp_backend_solaris_vas_platforms () {
3255     case `pp_backend_solaris_probe` in
3256         sol10-sparc* | sol9-sparc* | sol8-sparc*)
3257                         echo solaris8-sparc solaris7-sparc solaris26-sparc;;
3258         sol7-sparc*)    echo                solaris7-sparc solaris26-sparc;;
3259         sol26-sparc*)   echo                               solaris26-sparc;;
3260         sol8-*86)       echo solaris8-x86;;
3261         sol10-*86 | sol10-x86_64)
3262                         echo solaris10-x64 solaris8-x86;;
3263         *)              pp_die "unknown system `pp_backend_solaris_probe`";;
3264     esac
3265 }
3266 pp_backend_solaris_function() {
3267     case $1 in
3268         pp_mkgroup) cat<<'.';;
3269             /usr/sbin/groupmod "$1" 2>/dev/null && return 0
3270             /usr/sbin/groupadd "$1"
3271 .
3272         pp_mkuser:depends) echo pp_mkgroup;;
3273         pp_mkuser) cat<<'.';;
3274             id "$1" >/dev/null 2>/dev/null && return 0
3275             pp_mkgroup "${2:-$1}" || return 1
3276             /usr/sbin/useradd \
3277                 -g "${2:-$1}" \
3278                 -d "${3:-/nonexistent}" \
3279                 -s "${4:-/bin/false}" \
3280                 "$1"
3281 .
3282     *) false;;
3283     esac
3284 }
3285
3286 pp_backend_solaris_init_svc_vars () {
3287     pp_solaris_smf_category=
3288     pp_solaris_service_shell=/sbin/sh
3289 }
3290
3291 pp_solaris_init_svc () {
3292     smf_category=${pp_solaris_smf_category:-application}
3293     smf_version=1
3294     smf_type=service
3295     solaris_user=
3296     solaris_stop_signal=
3297     solaris_sysv_init_start=S70     # invocation order for start scripts
3298     solaris_sysv_init_kill=K30      # invocation order for kill scripts
3299     solaris_sysv_init_start_states="2" # states to install start link
3300     solaris_sysv_init_kill_states="S 0 1"  # states to install kill link
3301
3302     #
3303     # To have the service be installed to start automatically,
3304     #   %service foo
3305     #   solaris_sysv_init_start_states="S 0 1 2"
3306     #
3307 }
3308
3309 pp_solaris_smf () {
3310     typeset f
3311     f=/var/svc/manifest/$smf_category/$1
3312     pp_add_file_if_missing $f ||
3313         return 0
3314
3315     cat <<-. >$pp_destdir$f
3316         <?xml version="1.0"?>
3317         <!--
3318             $copyright
3319             Generated by PolyPackage $pp_version
3320         -->
3321
3322         <service name='$smf_category/$1'
3323                  type='$smf_type'
3324                  version='$smf_version'>
3325
3326             <single_instance />
3327
3328             <exec_method type='method' name='start'
3329                 exec=''
3330                 timeout_seconds='60'>
3331                 <method_context>
3332                   <method_credential user='${solaris_user:-$user}' />
3333                 </method_context>
3334             </exec>
3335
3336             <exec_method type='method' name='stop'
3337                 exec=':kill -${solaris_stop_signal:-$stop_signal}'>
3338                 <method_context>
3339                   <method_credential user='${solaris_user:-$user}' />
3340                 </method_context>
3341             </exec>
3342
3343         </service>
3344 .
3345 }
3346
3347 pp_solaris_make_service_group () {
3348     typeset group out file svcs svc
3349
3350     group="$1"
3351     svcs="$2"
3352     file="/etc/init.d/$group"
3353     out="$pp_destdir$file"
3354
3355     #-- return if the script is supplued already
3356     pp_add_file_if_missing "$file" run 755 || return 0
3357
3358     echo "#! /sbin/sh" > $out
3359     echo "# polypkg service group script for these services:" >> $out
3360     echo "svcs=\"$svcs\"" >> $out
3361
3362     cat <<'.' >>$out
3363
3364         #-- starts services in order.. stops them all if any break
3365         pp_start () {
3366             undo=
3367             for svc in $svcs; do
3368                 if /etc/init.d/$svc start; then
3369                     undo="$svc $undo"
3370                 else
3371                     if test -n "$undo"; then
3372                         for svc in $undo; do
3373                            /etc/init.d/$svc stop
3374                         done
3375                         return 1
3376                     fi
3377                 fi
3378             done
3379             return 0
3380         }
3381
3382         #-- stops services in reverse
3383         pp_stop () {
3384             reverse=
3385             for svc in $svcs; do
3386                 reverse="$svc $reverse"
3387             done
3388             rc=0
3389             for svc in $reverse; do
3390                 /etc/init.d/$svc stop || rc=$?
3391             done
3392             return $rc
3393         }
3394
3395         #-- returns true only if all services return true status
3396         pp_status () {
3397             rc=0
3398             for svc in $svcs; do
3399                 /etc/init.d/$svc status || rc=$?
3400             done
3401             return $rc
3402         }
3403
3404         case "$1" in
3405             start)   pp_start;;
3406             stop)    pp_stop;;
3407             status)  pp_status;;
3408             restart) pp_stop && pp_start;;
3409             *)       echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
3410         esac
3411 .
3412 }
3413
3414
3415 pp_solaris_make_service () {
3416     typeset file out _cmd svc
3417
3418     svc="$1"
3419     file="/etc/init.d/$svc"
3420     out="$pp_destdir$file"
3421
3422
3423     #-- return if we don't need to create the init script
3424     pp_add_file_if_missing "$file" run 755 ||
3425         return 0
3426
3427     echo "#! /sbin/sh" >$out
3428     echo "#-- This service init file generated by polypkg" >>$out
3429
3430     #-- construct a start command that builds a pid file as needed
3431     #   and forks the daemon
3432     _cmd="$cmd";
3433     if test -z "$pidfile"; then
3434         # The service does not define a pidfile, so we have to make
3435         # our own up. On Solaris systems where there is no /var/run
3436         # we must use /tmp to guarantee the pid files are removed after
3437         # a system crash.
3438         cat <<. >>$out
3439             pp_piddir="/var/run"
3440             test -d "\$pp_piddir/." || pp_piddir="/tmp"
3441             pidfile="\$pp_piddir/$svc.pid"
3442 .
3443         _cmd="$cmd & echo \$! > \$pidfile"
3444     else
3445         # The service is able to write its own PID file
3446         cat <<. >>$out
3447             pidfile="$pidfile"
3448 .
3449     fi
3450
3451     if test "${user:-root}" != "root"; then
3452         _cmd="su $user -c exec $_cmd";
3453     fi
3454
3455     cat <<. >>$out
3456         stop_signal="${stop_signal:-TERM}"
3457         svc="${svc}"
3458
3459         # generated command to run $svc as a daemon process
3460         pp_exec () { $_cmd; }
3461 .
3462
3463     #-- write the invariant section of the init script
3464     cat <<'.' >>$out
3465
3466         # returns true if $svc is running
3467         pp_running () {
3468             test -r "$pidfile" &&
3469             read pid junk < "$pidfile" &&
3470             test ${pid:-0} -gt 1 &&
3471             kill -0 "$pid" 2>/dev/null
3472         }
3473
3474         # prints a message describing $svc's running state
3475         pp_status () {
3476             if pp_running; then
3477                 echo "service $svc is running (pid $pid)"
3478                 return 0
3479             elif test -f "$pidfile"; then
3480                 echo "service $svc is not running, but pid file exists"
3481                 return 2
3482             else
3483                 echo "service $svc is not running"
3484                 return 1
3485             fi
3486         }
3487
3488         # starts $svc
3489         pp_start () {
3490             if pp_running; then
3491                 echo "service $svc already running" >&2
3492                 return 0
3493             fi
3494             echo "starting $svc... \c"
3495             if pp_exec; then
3496                 echo "done."
3497             else
3498                 echo "ERROR."
3499                 exit 1
3500             fi
3501         }
3502
3503         # stops $svc
3504         pp_stop () {
3505             if pp_running; then
3506                 echo "stopping $svc... \c"
3507                 if kill -$stop_signal $pid; then
3508                     rm -f "$pidfile"
3509                     echo "done."
3510                 else
3511                     echo "ERROR."
3512                     return 1
3513                 fi
3514             else
3515                 echo "service $svc already stopped" >&2
3516                 return 0
3517             fi
3518         }
3519
3520         umask 022
3521         case "$1" in
3522             start)   pp_start;;
3523             stop)    pp_stop;;
3524             status)  pp_status;;
3525             restart) pp_stop && pp_start;;
3526             *)       echo "usage: $0 {start|stop|restart|status}" >&2; exit 1;;
3527         esac
3528 .
3529 }
3530
3531
3532 pp_solaris_install_service () {
3533     typeset s k l
3534     s="${solaris_sysv_init_start}$1"
3535     k="${solaris_sysv_init_kill}$1"
3536
3537     echo 'case " $SERVICES " in *" '$1' "*)'
3538     echo '
3539 if [ "x${PKG_INSTALL_ROOT}" != "x" ]; then
3540   if [ -x ${PKG_INSTALL_ROOT}/usr/sbin/svcadm ]; then
3541     echo "/usr/sbin/svccfg import '$pp_svc_xml_file' 2>/dev/null" >> ${PKG_INSTALL_ROOT}/var/svc/profile/upgrade
3542   else'
3543     test -n "${solaris_sysv_init_start_states}" &&
3544         for state in ${solaris_sysv_init_start_states}; do
3545             l="/etc/rc$state.d/$s"
3546             echo "echo '$l'"
3547             echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
3548             pp_solaris_space /etc/rc$state.d 0 1
3549         done
3550     test -n "${solaris_sysv_init_kill_states}" &&
3551         for state in ${solaris_sysv_init_kill_states}; do
3552             l="/etc/rc$state.d/$k"
3553             echo "echo '$l'"
3554             echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
3555             pp_solaris_space /etc/rc$state.d 0 1
3556         done
3557     echo '
3558   fi
3559 else
3560     if [ -x /usr/sbin/svcadm ]; then
3561         echo "Registering '$1' with SMF"
3562         /usr/sbin/svcadm disable -s '$1' 2>/dev/null
3563         /usr/sbin/svccfg delete '$1' 2>/dev/null
3564         /usr/sbin/svccfg import '$pp_svc_xml_file' 2>/dev/null
3565     else'
3566     test -n "${solaris_sysv_init_start_states}" &&
3567         for state in ${solaris_sysv_init_start_states}; do
3568             l="/etc/rc$state.d/$s"
3569             echo "echo '$l'"
3570             echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
3571             pp_solaris_space /etc/rc$state.d 0 1
3572         done
3573     test -n "${solaris_sysv_init_kill_states}" &&
3574         for state in ${solaris_sysv_init_kill_states}; do
3575             l="/etc/rc$state.d/$k"
3576             echo "echo '$l'"
3577             echo "installf -c run \$PKGINST \$PKG_INSTALL_ROOT$l=../init.d/$1 s"
3578             pp_solaris_space /etc/rc$state.d 0 1
3579         done
3580     echo " :;; esac"
3581
3582 }
3583
3584 pp_platforms="$pp_platforms deb"
3585
3586 pp_backend_deb_detect () {
3587     test -f /etc/debian_version
3588 }
3589
3590 pp_deb_cmp_full_name () {
3591     local prefix
3592     prefix="${pp_deb_name:-$name}"
3593     case "$1" in
3594         run) echo "${prefix}" ;;
3595         dbg) echo "${prefix}-${pp_deb_dbg_pkgname}";;
3596         dev) echo "${prefix}-${pp_deb_dev_pkgname}";;
3597         doc) echo "${prefix}-${pp_deb_doc_pkgname}";;
3598         *)   pp_error "unknown component '$1'";
3599     esac
3600 }
3601
3602 pp_backend_deb_init () {
3603     pp_deb_dpkg_version="2.0"
3604     pp_deb_name=
3605     pp_deb_version=
3606     pp_deb_release=
3607     pp_deb_arch=
3608     pp_deb_arch_std=
3609     pp_deb_maintainer=support@quest.com
3610     pp_deb_copyright=
3611     pp_deb_distro=
3612     pp_deb_control_description=
3613     pp_deb_summary=
3614     pp_deb_description=
3615     pp_deb_dbg_pkgname="dbg"
3616     pp_deb_dev_pkgname="dev"
3617     pp_deb_doc_pkgname="doc"
3618     pp_deb_section=contrib # Free software that depends on non-free software
3619
3620     # Detect the host architecture
3621     pp_deb_detect_arch
3622
3623     # Make sure any programs we require are installed
3624     pp_deb_check_required_programs
3625
3626     # Set generated/interrogated platforms variables
3627     pp_deb_munge_description
3628 }
3629
3630 pp_deb_check_required_programs () {
3631     local p needed notfound ok
3632     needed= notfound=
3633     for prog in dpkg dpkg-deb install md5sum fakeroot
3634     do
3635         if which $prog 2>/dev/null >/dev/null; then
3636             pp_debug "$prog: found"
3637         else
3638             pp_debug "$prog: not found"
3639             case "$prog" in
3640                 dpkg|dpkg-deb)  p=dpkg;;
3641                 install|md5sum) p=coreutils;;
3642                 fakeroot)       p=fakeroot;;
3643                 *)              pp_die "unexpected dpkg tool $prog";;
3644             esac
3645             notfound="$notfound $prog"
3646             pp_contains "$needed" "$p" || needed="$needed $p"
3647         fi
3648     done
3649     if [ -n "$notfound" ]; then
3650         pp_error "cannot find these programs: $notfound"
3651         pp_error "please install these packages: $needed"
3652     fi
3653 }
3654
3655 pp_deb_munge_description () {
3656     # Insert a leading space on each line, replace blank lines with a
3657     #space followed by a full-stop.
3658     pp_deb_control_description=`echo ${pp_deb_description:-$description} | \
3659         sed "s,^\(.*\)$, \1, " \
3660         | sed "s,^[ \t]*$, .,g"`
3661
3662 }
3663
3664 pp_deb_detect_arch () {
3665    pp_deb_arch=`dpkg --print-architecture`
3666    pp_deb_arch_std=`uname -m`
3667 }
3668
3669 pp_deb_make_control() {
3670     package_name=`pp_deb_cmp_full_name "$1"`
3671     cat <<-.
3672         Package: ${package_name}
3673         Version: ${pp_deb_version:-$version}-${pp_deb_release:-1}
3674         Section: ${pp_deb_section:-contrib}
3675         Priority: optional
3676         Architecture: ${pp_deb_arch}
3677         Maintainer: ${pp_deb_maintainer:-$maintainer}
3678         Description: ${pp_deb_summary:-$summary}
3679         ${pp_deb_control_description}
3680 .
3681     if test -s $pp_wrkdir/%depend."$1"; then
3682         sed -ne '/^[    ]*$/!s/^[       ]*/Depends: /p' \
3683             < $pp_wrkdir/%depend."$1"
3684     fi
3685 }
3686
3687 pp_deb_make_md5sums() {
3688     local cmp="$1"; shift
3689     local pkg_dir
3690
3691     pkg_dir=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
3692     (cd $pkg_dir && md5sum "$@") > $pkg_dir/DEBIAN/md5sums ||
3693         pp_error "cannot make md5sums"
3694 }
3695
3696 pp_deb_make_package_maintainer_script() {
3697     local output="$1"
3698     local source="$2"
3699     local desc="$3"
3700
3701     # See if we need to create this script at all
3702     if [ -s "$source" ]
3703     then
3704
3705         # Create header
3706         cat <<-. >$output || pp_error "Cannot create $output"
3707         #!/bin/sh
3708         # $desc
3709         # Generated by PolyPackage $pp_version
3710
3711 .
3712
3713         cat $source >> "$output" || pp_error "Cannot append to $output"
3714
3715         # Set perms
3716         chmod 755 "$output" || pp_error "Cannot chmod $output"
3717     fi
3718 }
3719
3720 pp_deb_handle_services() {
3721     local svc
3722
3723     #-- add service start/stop code
3724     if test -n "$pp_services"; then
3725         #-- record the uninstall commands in reverse order
3726         for svc in $pp_services; do
3727             pp_load_service_vars $svc
3728
3729             # Create init script (unless one exists)
3730             pp_deb_service_make_init_script $svc
3731
3732             #-- append %post code to install the svc
3733             test x"yes" = x"$enable" &&
3734             cat<<-. >> $pp_wrkdir/%post.run
3735                 # Install the service links
3736                 /usr/sbin/update-rc.d $svc defaults
3737 .
3738
3739             #-- prepend %preun code to stop svc
3740             cat<<-. | pp_prepend $pp_wrkdir/%preun.run
3741                 # Stop the $svc service
3742                 if test -x /usr/sbin/invoke-rc.d; then
3743                     /usr/sbin/invoke-rc.d $svc stop
3744                 else
3745                     /etc/init.d/$svc stop
3746                 fi
3747                 # Remove the service links
3748                 /usr/sbin/update-rc.d -f $svc remove
3749 .
3750         done
3751         #pp_deb_service_remove_common | pp_prepend $pp_wrkdir/%preun.run
3752     fi
3753
3754 }
3755 pp_deb_fakeroot () {
3756     if test -s $pp_wrkdir/fakeroot.save; then
3757         fakeroot -i $pp_wrkdir/fakeroot.save -s $pp_wrkdir/fakeroot.save "$@"
3758     else
3759         fakeroot -s $pp_wrkdir/fakeroot.save "$@"
3760     fi
3761 }
3762
3763 pp_deb_make_DEBIAN() {
3764     local cmp="${1:-run}"
3765     local data cmp_full_name
3766     local old_umask
3767
3768     old_umask=`umask`
3769     umask 0022
3770     cmp_full_name=`pp_deb_cmp_full_name $cmp`
3771     data=$pp_wrkdir/$cmp_full_name
3772
3773     # Create DEBIAN dir $data/DEBIAN
3774     mkdir -p $data/DEBIAN
3775
3776     # Create control file
3777     pp_deb_make_control $cmp > $data/DEBIAN/control
3778
3779     # Copy in conffiles
3780     if test -f $pp_wrkdir/%conffiles.$cmp; then
3781         cp $pp_wrkdir/%conffiles.$cmp $data/DEBIAN/conffiles
3782     fi
3783
3784     # Create postinst
3785     pp_deb_make_package_maintainer_script "$data/DEBIAN/postinst" \
3786         "$pp_wrkdir/%post.$cmp" "Post install script for $cmp_full_name"\
3787         || exit $?
3788
3789     # Create prerm
3790     pp_deb_make_package_maintainer_script "$data/DEBIAN/prerm" \
3791         "$pp_wrkdir/%preun.$cmp" "Pre-uninstall script for $cmp_full_name"\
3792         || exit $?
3793
3794     umask $old_umask
3795 }
3796
3797 pp_deb_make_data() {
3798     local _l t m o g f p st data
3799     local data share_doc owner group
3800     cmp=$1
3801     data=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
3802     cat $pp_wrkdir/%files.${cmp} | while read t m o g f p st; do
3803         test x"$o" = x"-" && o=root
3804         test x"$g" = x"-" && g=root
3805         case "$t" in
3806         f) # Files
3807            pp_deb_fakeroot install -D -o $o -g $g -m ${m} $pp_destdir/$p $data/$p;
3808            if [ x"$f" = x"v" ]
3809            then
3810                # File marked as "volatile". Assume this means it's a conffile
3811                # TODO: check this as admins like modified conffiles to be left
3812                #       behind
3813                echo "$p" >> $pp_wrkdir/%conffiles.$cmp
3814            fi;;
3815
3816         d) # Directories
3817            pp_deb_fakeroot install -m ${m} -o $o -g $g -d $data/$p;;
3818
3819         s) # Symlinks
3820            # Remove leading / from vars
3821            rel_p=`echo $p | sed s,^/,,`
3822            rel_st=`echo $st | sed s,^/,,`
3823            # TODO: we are always doing absolute links here. We should follow
3824            # the debian policy of relative links when in the same top-level
3825            # directory
3826            (cd $data; ln -sf $st $rel_p);;
3827             *) pp_error "Unsupported data file type: $t";;
3828         esac
3829     done
3830
3831     # If no copyright file is present add one. This is a debian requirement.
3832     share_doc="/usr/share/doc/`pp_deb_cmp_full_name $cmp`"
3833     if [ ! -f "$data/$share_doc/copyright" ]
3834     then
3835         echo "${pp_deb_copyright:-$copyright}" > "$pp_wrkdir/copyright"
3836         install -D -m 644 "$pp_wrkdir/copyright" "$data/$share_doc/copyright"
3837     fi
3838
3839 }
3840
3841 pp_deb_makedeb () {
3842     local cmp
3843     local package_build_dir
3844
3845     cmp="$1"
3846
3847     package_build_dir=$pp_wrkdir/`pp_deb_cmp_full_name $cmp`
3848
3849     # Create package dir
3850     mkdir -p $package_build_dir
3851
3852     # Copy in data
3853     pp_deb_make_data $cmp ||
3854         pp_die "Could not make DEBIAN data files for $cmp"
3855
3856     # Make control files
3857     # must be done after copying data so conffiles are found
3858     pp_deb_make_DEBIAN $cmp ||
3859         pp_die "Could not make DEBIAN control files for $cmp"
3860
3861     # Create md5sums
3862     pp_deb_make_md5sums $cmp `(cd $package_build_dir;
3863         find . -type f -a -not -name DEBIAN | sed "s,^\./,,")` ||
3864             pp_die "Could not make DEBIAN md5sums for $cmp"
3865 }
3866
3867 pp_backend_deb () {
3868     local debname
3869
3870     # Handle services
3871     pp_deb_handle_services $cmp
3872
3873     for cmp in $pp_components
3874     do
3875         debname=`pp_deb_name $cmp`
3876         pp_deb_makedeb $cmp
3877     done
3878
3879     . $pp_wrkdir/%fixup
3880
3881     for cmp in $pp_components
3882     do
3883         debname=`pp_deb_name $cmp`
3884         # Create debian package
3885         pp_debug "Building `pp_deb_cmp_full_name $cmp` -> $output"
3886         pp_deb_fakeroot dpkg-deb \
3887             --build $pp_wrkdir/`pp_deb_cmp_full_name $cmp` \
3888             $pp_wrkdir/$debname ||
3889                 pp_error "failed to create $cmp package"
3890     done
3891 }
3892
3893 pp_backend_deb_cleanup () {
3894     # rm -rf $pp_wrkdir
3895     :
3896 }
3897
3898 pp_deb_name () {
3899     local cmp="${1:-run}"
3900     echo `pp_deb_cmp_full_name $cmp`"_${pp_deb_version:-$version}-${pp_deb_release:-1}_${pp_deb_arch}.deb"
3901 }
3902 pp_backend_deb_names () {
3903     for cmp in $pp_components
3904     do
3905         pp_deb_name $cmp
3906     done
3907 }
3908
3909 pp_backend_deb_install_script () {
3910     local cmp _cmp_full_name
3911
3912     echo "#!/bin/sh"
3913     pp_install_script_common
3914
3915     cat <<.
3916
3917         cmp_to_pkgname () {
3918             test x"\$*" = x"all" &&
3919                 set -- $pp_components
3920             for cmp
3921             do
3922                 case \$cmp in
3923 .
3924     for cmp in $pp_components; do
3925          echo "$cmp) echo '`pp_deb_cmp_full_name $cmp`';;"
3926     done
3927     cat <<.
3928                 *) usage;;
3929                 esac
3930             done
3931         }
3932
3933
3934         cmp_to_pathname () {
3935             test x"\$*" = x"all" &&
3936                 set -- $pp_components
3937             for cmp
3938             do
3939                 case \$cmp in
3940 .
3941     for cmp in $pp_components; do
3942          echo "$cmp) echo \${PP_PKGDESTDIR:-.}/'`pp_deb_name $cmp`';;"
3943     done
3944     cat <<.
3945                 *) usage;;
3946                 esac
3947             done
3948         }
3949
3950         test \$# -eq 0 && usage
3951         op="\$1"; shift
3952         case "\$op" in
3953             list-components)
3954                 test \$# -eq 0 || usage \$op
3955                 echo $pp_components
3956                 ;;
3957             list-services)
3958                 test \$# -eq 0 || usage \$op
3959                 echo $pp_services
3960                 ;;
3961             list-files)
3962                 test \$# -ge 1 || usage \$op
3963                 cmp_to_pathname "\$@"
3964                 ;;
3965             install)
3966                 test \$# -ge 1 || usage \$op
3967                 dpkg --install \`cmp_to_pathname "\$@"\`
3968                 ;;
3969             uninstall)
3970                 test \$# -ge 1 || usage \$op
3971                 dpkg --remove \`cmp_to_pkgname "\$@"\`; :
3972                 ;;
3973             start|stop)
3974                 test \$# -ge 1 || usage \$op
3975                 ec=0
3976                 for svc
3977                 do
3978                     /etc/init.d/\$svc \$op || ec=1
3979                 done
3980                 exit \$ec
3981                 ;;
3982             print-platform)
3983                 test \$# -eq 0 || usage \$op
3984                 echo "linux-${pp_deb_arch}"
3985                 ;;
3986             *)
3987                 usage
3988                 ;;
3989         esac
3990 .
3991 }
3992
3993 pp_backend_deb_probe() {
3994     local arch distro release
3995
3996     pp_deb_detect_arch
3997
3998     # /etc/debian_version exists on Debian & Ubuntu, so it's no use
3999     # to us. Use lsb_release instead.
4000
4001     case `(lsb_release -is || echo no-lsb) 2>/dev/null` in
4002         Debian)
4003             distro=deb
4004             ;;
4005         Ubuntu)
4006             distro=ubu
4007             ;;
4008         no-lsb)
4009             echo unknown-$pp_deb_arch_std
4010             return 0
4011             ;;
4012         *)
4013             distro=unknown
4014             ;;
4015     esac
4016
4017     release=`lsb_release -rs`
4018
4019     # If release is not numeric, use the codename
4020     case $release in
4021         *[!.0-9r]*)
4022             release=`lsb_release -cs`
4023             case $release in
4024                 buzz)
4025                     release="11"
4026                     ;;
4027                 rex)
4028                     release="12"
4029                     ;;
4030                 bo)
4031                     release="13"
4032                     ;;
4033                 hamm)
4034                     release="20"
4035                     ;;
4036                 slink)
4037                     release="21"
4038                     ;;
4039                 potato)
4040                     release="22"
4041                     ;;
4042                 woody)
4043                     release="30"
4044                     ;;
4045                 sarge)
4046                     release="31"
4047                     ;;
4048                 etch)
4049                     release="40"
4050                     ;;
4051                 lenny)
4052                     release="50"
4053                     ;;
4054                 squeeze)
4055                     release="60"
4056                     ;;
4057             esac
4058             ;;
4059         *)
4060             # Remove trailing revision number and any dots
4061             release=`echo $release | cut -dr -f1 | tr -d .`
4062             ;;
4063     esac
4064
4065     echo $distro$release-$pp_deb_arch_std
4066 }
4067
4068 pp_backend_deb_vas_platforms () {
4069     case "$pp_deb_arch_std" in
4070         x86_64) echo "linux-x86_64.deb";; # DO NOT add linux-x86.deb here!!
4071         *86)    echo "linux-x86.deb";;
4072         *)      pp_die "unknown architecture ${pp_deb_arch_std}";;
4073     esac
4074 }
4075 pp_backend_deb_init_svc_vars () {
4076     # Default multi-user runlevel on Debian is 2; 3-5 are also multi-user
4077     pp_deb_default_start_runlevels="2 3 4 5"
4078     pp_deb_default_svc_description="No description"
4079 }
4080
4081 pp_backend_deb_init_svc_vars () {
4082
4083     reload_signal=
4084     start_runlevels=${pp_deb_default_start_runlevels}   # == lsb default-start
4085     stop_runlevels="0 1 6"                              # == lsb default-stop
4086     svc_description="${pp_deb_default_svc_description}" # == lsb short descr
4087     svc_process=
4088
4089     lsb_required_start='$local_fs $network'
4090     lsb_should_start=
4091     lsb_required_stop=
4092     lsb_description=
4093
4094     start_priority=50
4095     stop_priority=50            #-- stop_priority = 100 - start_priority
4096 }
4097
4098 pp_deb_service_make_init_script () {
4099     local svc=$1
4100     local script=/etc/init.d/$svc
4101     local out=$pp_destdir$script
4102     local _process _cmd
4103
4104     pp_add_file_if_missing $script run 755 || return 0
4105
4106     #-- start out as an empty shell script
4107     cat <<-'.' >$out
4108         #!/bin/sh
4109 .
4110
4111     #-- determine the process name from $cmd unless $svc_process is given
4112     set -- $cmd
4113     #_process=${svc_process:-"$1"} --? WTF
4114
4115     #-- construct a start command that builds a pid file if needed
4116     _cmd="$cmd";
4117     _cmd_path=`echo $cmd | cut -d" " -f1`
4118     _cmd_name=`basename $_cmd_path`
4119     _cmd_args=`echo $cmd | cut -d" " -f2-`
4120     test x"$_cmd_path" != x"$_cmd_args" || _cmd_args=
4121
4122     #-- generate the LSB init info
4123     cat <<-. >>$out
4124         ### BEGIN INIT INFO
4125         # Provides: ${svc}
4126         # Required-Start: ${lsb_required_start}
4127         # Should-Start: ${lsb_should_start}
4128         # Required-Stop: ${lsb_required_stop}
4129         # Default-Start: ${start_runlevels}
4130         # Default-Stop: ${stop_runlevels}
4131         # Short-Description: ${svc_description}
4132         ### END INIT INFO
4133         # Generated by PolyPackage ${pp_version}
4134         # ${copyright}
4135
4136 .
4137
4138     if test x"${svc_description}" = x"${pp_deb_default_svc_description}"; then
4139         svc_description=
4140     fi
4141
4142     #-- write service-specific definitions
4143     cat <<. >>$out
4144 NAME="${_cmd_name}"
4145 DESC="${svc_description:-$svc service}"
4146 USER="${user}"
4147 GROUP="${group}"
4148 PIDFILE="${pidfile}"
4149 STOP_SIGNAL="${stop_signal}"
4150 RELOAD_SIGNAL="${reload_signal}"
4151 CMD="${_cmd}"
4152 DAEMON="${_cmd_path}"
4153 DAEMON_ARGS="${_cmd_args}"
4154 SCRIPTNAME=${script}
4155 .
4156
4157     #-- write the generic part of the init script
4158     cat <<'.' >>$out
4159
4160 [ -x "$DAEMON" ] || exit 0
4161
4162 [ -r /etc/default/$NAME ] && . /etc/default/$NAME
4163
4164 [ -f /etc/default/rcS ] && . /etc/default/rcS
4165
4166 . /lib/lsb/init-functions
4167
4168 do_start()
4169 {
4170         # Return
4171         #   0 if daemon has been started
4172         #   1 if daemon was already running
4173         #   2 if daemon could not be started
4174     if [ -n "$PIDFILE" ]
4175     then
4176         pidfile_opt="--pidfile $PIDFILE"
4177     else
4178         pidfile_opt="--make-pidfile --background --pidfile /var/run/$NAME.pid"
4179     fi
4180     if [ -n "$USER" ]
4181     then
4182         user_opt="--user $USER"
4183     fi
4184     if [ -n "$GROUP" ]
4185     then
4186         group_opt="--group $GROUP"
4187     fi
4188     if [ "$VERBOSE" = no ]
4189     then
4190         quiet_opt="--quiet"
4191     else
4192         quiet_opt="--verbose"
4193     fi
4194
4195         start-stop-daemon --start $quiet_opt $pidfile_opt $user_opt --exec $DAEMON --test > /dev/null \
4196             || return 1
4197
4198     # Note: there seems to be no way to tell whether the daemon will fork itself or not, so pass
4199     # --background for now
4200     start-stop-daemon --start $quiet_opt $pidfile_opt $user_opt --exec $DAEMON -- \
4201         $DAEMON_ARGS \
4202         || return 2
4203 }
4204
4205 do_stop()
4206 {
4207         # Return
4208         #   0 if daemon has been stopped
4209         #   1 if daemon was already stopped
4210         #   2 if daemon could not be stopped
4211         #   other if a failure occurred
4212     if [ -n "$PIDFILE" ]
4213     then
4214         pidfile_opt="--pidfile $PIDFILE"
4215     else
4216         pidfile_opt="--pidfile /var/run/$NAME.pid"
4217     fi
4218     if [ -n "$USER" ]
4219     then
4220         user_opt="--user $USER"
4221     fi
4222     if [ -n $STOP_SIGNAL ]
4223     then
4224         signal_opt="--signal $STOP_SIGNAL"
4225     fi
4226     if [ "$VERBOSE" = "no" ]
4227     then
4228         quiet_opt="--quiet"
4229     else
4230         quiet_opt="--verbose"
4231     fi
4232         start-stop-daemon --stop $quiet_opt $signal_opt --retry=TERM/30/KILL/5 $pidfile_opt --name $NAME
4233         RETVAL="$?"
4234         [ "$RETVAL" = 2 ] && return 2
4235         # Wait for children to finish too if this is a daemon that forks
4236         # and if the daemon is only ever run from this initscript.
4237         # If the above conditions are not satisfied then add some other code
4238         # that waits for the process to drop all resources that could be
4239         # needed by services started subsequently.  A last resort is to
4240         # sleep for some time.
4241         start-stop-daemon --stop $quiet_opt --oknodo --retry=0/30/KILL/5 --exec $DAEMON
4242         [ "$?" = 2 ] && return 2
4243         # Many daemons don't delete their pidfiles when they exit.
4244         test -z $PIDFILE || rm -f $PIDFILE
4245         return "$RETVAL"
4246 }
4247
4248 do_reload() {
4249         #
4250         # If the daemon can reload its configuration without
4251         # restarting (for example, when it is sent a SIGHUP),
4252         # then implement that here.
4253         #
4254     if [ -n "$PIDFILE" ]
4255     then
4256         pidfile_opt="--pidfile $PIDFILE"
4257     else
4258         pidfile_opt="--pidfile /var/run/$NAME.pid"
4259     fi
4260     if [ -n "$RELOAD_SIGNAL" ]
4261     then
4262             start-stop-daemon --stop --signal $RELOAD_SIGNAL $quiet_opt $pidfile_opt --name $NAME
4263     fi
4264         return 0
4265 }
4266
4267 case "$1" in
4268   start)
4269         [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
4270         do_start
4271         case "$?" in
4272                 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
4273                 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
4274         esac
4275         ;;
4276   stop)
4277         [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
4278         do_stop
4279         case "$?" in
4280                 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
4281                 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
4282         esac
4283         ;;
4284   reload|force-reload)
4285     if [ -n "$RELOAD_SIGNAL" ]
4286     then
4287             log_daemon_msg "Reloading $DESC" "$NAME"
4288             do_reload
4289             log_end_msg $?
4290     else
4291         # Do a restart instead
4292         "$0" restart
4293     fi
4294         ;;
4295   restart)
4296         #
4297         # If the "reload" option is implemented then remove the
4298         # 'force-reload' alias
4299         #
4300         log_daemon_msg "Restarting $DESC" "$NAME"
4301         do_stop
4302         case "$?" in
4303           0|1)
4304                 do_start
4305                 case "$?" in
4306                         0) log_end_msg 0 ;;
4307                         1) log_end_msg 1 ;; # Old process is still running
4308                         *) log_end_msg 1 ;; # Failed to start
4309                 esac
4310                 ;;
4311           *)
4312                 # Failed to stop
4313                 log_end_msg 1
4314                 ;;
4315         esac
4316         ;;
4317   *)
4318         #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
4319         echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
4320         exit 3
4321         ;;
4322 esac
4323
4324 :
4325 .
4326     chmod 755 $out
4327 }
4328 pp_backend_deb_function() {
4329     case $1 in
4330         pp_mkgroup) cat<<'.';;
4331             /usr/sbin/groupmod "$1" 2>/dev/null && return 0
4332             /usr/sbin/groupadd "$1"
4333 .
4334         pp_mkuser:depends) echo pp_mkgroup;;
4335         pp_mkuser) cat<<'.';;
4336             pp_tmp_system=
4337             id -u "$1" >/dev/null 2>/dev/null && return 0
4338             # deb 3.1's useradd changed API in 4.0. Gah!
4339             /usr/sbin/useradd --help 2>&1 | /bin/grep -q .--system &&
4340                 pp_tmp_system=--system
4341             pp_mkgroup "${2:-$1}" || return 1
4342             /usr/sbin/useradd \
4343                 -g "${2:-$1}" \
4344                 -d "${3:-/nonexistent}" \
4345                 -s "${4:-/bin/false}" \
4346                 $pp_tmp_system \
4347                 "$1"
4348 .
4349         pp_havelib) cat<<'.';;
4350             for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
4351                 test -r "$pp_tmp_dir/lib$1.so{$2:+.$2}" && return 0
4352             done
4353             return 1
4354 .
4355     *) false;;
4356     esac
4357 }
4358
4359 pp_platforms="$pp_platforms kit"
4360
4361 pp_backend_kit_detect () {
4362     test x"$1" = x"OSF1"
4363 }
4364
4365 pp_backend_kit_init () {
4366         pp_kit_name=
4367         pp_kit_package=
4368         pp_kit_desc=
4369         pp_kit_version=
4370         pp_kit_subset=
4371         pp_readlink_fn=pp_ls_readlink
4372         pp_kit_startlevels="2 3"
4373         pp_kit_stoplevels="0 2 3"
4374 }
4375
4376 pp_backend_kit () {
4377     typeset mi_file k_file svc outfile
4378     typeset desc
4379
4380     pp_backend_kit_names > /dev/null
4381
4382     if test -z "$pp_kit_desc"; then
4383         pp_kit_desc="$description"
4384     fi
4385
4386     mi_file="$pp_wrkdir/$pp_kit_subset.mi"
4387     k_file="$pp_wrkdir/$pp_kit_subset.k"
4388     scp_file="$pp_wrkdir/$pp_kit_subset.scp"
4389
4390     desc="${pp_kit_desc:-$description}"
4391
4392     cat <<-. >> $k_file
4393         NAME='$name'
4394         CODE=$pp_kit_name
4395         VERS=$pp_kit_version
4396         MI=$mi_file
4397         COMPRESS=0
4398         %%
4399         $pp_kit_subset  .       0       '$desc'
4400 .
4401
4402     if test -n "$pp_services"; then
4403         for svc in $pp_services; do
4404             pp_kit_make_service $svc
4405             pp_prepend $pp_wrkdir/%preun.run <<-.
4406                 /sbin/init.d/$svc stop
4407 .
4408          done
4409     fi
4410
4411     pp_backend_kit_make_mi "$mi_file"
4412     pp_backend_kit_make_scp
4413     #rm -rf  $pp_wrkdir/kit_dest
4414     mkdir -p $pp_wrkdir/kit_dest
4415     pp_backend_kit_kits $k_file $pp_opt_destdir $pp_wrkdir/kit_dest
4416     tar cvf $pp_wrkdir/$pp_kit_subset.tar -C $pp_wrkdir/kit_dest .
4417     gzip -c $pp_wrkdir/$pp_kit_subset.tar > $pp_wrkdir/$pp_kit_subset.tar.gz
4418     #rm -rf $pp_wrkdir/$pp_kit_subset.tar $pp_wrkdir/scps
4419 }
4420
4421 pp_backend_kit_make_mi () {
4422     # XXX this information should go into the .inv files
4423     typeset t m o g f p st line dm
4424     while read t m o g f p st; do
4425         case $t in
4426             f|d)
4427                 echo "0 .$p     $pp_kit_subset"
4428                 echo "        chmod $m $p" >> $pp_wrkdir/%post.run
4429                 if [ x"$o" = x"-" ] ; then
4430                     echo "        chown root $p" >> $pp_wrkdir/%post.run
4431                 else
4432                     echo "        chown $o $p" >> $pp_wrkdir/%post.run
4433                 fi
4434                 if [ x"$g" = x"-" ] ; then
4435                     echo "        chgrp 0 $p" >> $pp_wrkdir/%post.run
4436                 else
4437                     echo "        chgrp $g $p" >> $pp_wrkdir/%post.run
4438                 fi
4439                 ;;
4440             s)
4441                 echo "        ln -s $st $p" >> $pp_wrkdir/%post.run
4442                 echo "        rm -f $p" >> $pp_wrkdir/%preun.run
4443                 ;;
4444          esac
4445     done < $pp_wrkdir/%files.run | sort -k3  |uniq > $1
4446 }
4447
4448
4449 pp_backend_kit_make_scp () {
4450     scpdir="$pp_wrkdir/scps"
4451     mkdir "$scpdir" && touch "$scpdir"/$pp_kit_subset.scp
4452     cat <<EOF >"$scpdir"/$pp_kit_subset.scp
4453
4454     . /usr/share/lib/shell/libscp
4455
4456     case "\$ACT" in
4457     PRE_L)
4458     STL_ScpInit
4459
4460
4461
4462     ;;
4463     POST_L)
4464         STL_ScpInit
4465         STL_LinkCreate
4466 EOF
4467
4468     cat $pp_wrkdir/%post.run >>"$scpdir"/$pp_kit_subset.scp
4469     cat >>"$scpdir"/$pp_kit_subset.scp <<EOF
4470     ;;
4471     PRE_D)
4472         STL_ScpInit
4473         STL_LinkRemove
4474 EOF
4475     cat $pp_wrkdir/%preun.run >>"$scpdir"/$pp_kit_subset.scp
4476     cat >>"$scpdir"/$pp_kit_subset.scp <<EOF
4477         ;;
4478     POST_D)
4479
4480         ;;
4481     C)
4482         STL_ScpInit
4483
4484         case "\$1" in
4485         INSTALL)
4486         echo "Installation of the \$_DESC (\$_SUB) subset is complete."
4487         ;;
4488     DELETE)
4489         ;;
4490     esac
4491
4492         ;;
4493     V)
4494
4495         ;;
4496     esac
4497
4498     exit 0
4499 EOF
4500     chmod 744 "$scpdir"/$pp_kit_subset.scp
4501 }
4502
4503
4504 pp_backend_kit_cleanup () {
4505     :
4506 }
4507
4508 pp_backend_kit_names () {
4509     if test -z "$pp_kit_name"; then
4510         pp_warn "pp_kit_name not specified, using XXX"
4511         pp_kit_name=XXX
4512     fi
4513     case "$pp_kit_name" in
4514         ???) : ok;;
4515         *) pp_error "\$pp_kit_name $pp_kit_name must be three characters";;
4516     esac
4517     if test -z "$pp_kit_package"; then
4518         pp_warn "pp_kit_package not specified, using YYYY"
4519         pp_kit_package=YYYY
4520     fi
4521     if test -z "$pp_kit_version"; then
4522         pp_kit_version=`echo $version|tr -d '.a-zA-Z'`
4523     fi
4524     case "$pp_kit_version" in
4525         [0-9]) pp_kit_version="${pp_kit_version}00";;
4526         [0-9][0-9]) pp_kit_version="${pp_kit_version}0";;
4527         [0-9][0-9][0-9]) : ok;;
4528         *) pp_error "\$pp_kit_version $pp_kit_version must be three digits, ";;
4529     esac
4530     if test -z "$pp_kit_subset"; then
4531         pp_kit_subset="$pp_kit_name$pp_kit_package$pp_kit_version"
4532     fi
4533     echo "$pp_kit_subset.tar.gz"
4534 }
4535
4536 pp_backend_kit_install_script () {
4537     typeset pkgname platform
4538
4539     pkgname=`pp_backend_kit_names`
4540     platform="`pp_backend_kit_probe`"
4541
4542     echo "#!/bin/sh"
4543     pp_install_script_common
4544     cat <<.
4545
4546         cpt_to_tags () {
4547             test x"\$*" = x"all" && set -- $pp_components
4548             for cpt
4549             do
4550                 echo "$name.\$cpt"
4551             done
4552         }
4553
4554         test \$# -eq 0 && usage
4555         op="\$1"; shift
4556
4557         case "\$op" in
4558             list-components)
4559                 test \$# -eq 0 || usage \$op
4560                 echo "$pp_components"
4561                 ;;
4562             list-services)
4563                 test \$# -eq 0 || usage \$op
4564                 echo "$pp_services"
4565                 ;;
4566             list-files)
4567                 test \$# -ge 1 || usage \$op
4568                 echo \${PP_PKGDESTDIR:-.}/$pkgname
4569                 ;;
4570             install)
4571                 test \$# -ge 1 || usage \$op
4572                 verbose echo \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \`cpt_to_tags "\$@"\`
4573                 #verbose swinstall -x verbose=0 -s \${PP_PKGDESTDIR:-\`pwd\`}/$pkgname \`cpt_to_tags "\$@"\`
4574                 ;;
4575             uninstall)
4576                 test \$# -ge 1 || usage \$op
4577                 verbose echo \`cpt_to_tags "\$@"\`
4578                 #verbose swremove -x verbose=0 \`cpt_to_tags "\$@"\`
4579                 ;;
4580             start|stop)
4581                 test \$# -ge 1 || usage \$op
4582                 ec=0
4583                 for svc
4584                 do
4585                     verbose /sbin/init.d/\$svc \$op
4586                     [ \$? -eq 4 -o \$? -eq 0 ] || ec=1
4587                 done
4588                 exit \$ec
4589                 ;;
4590             print-platform)
4591                 echo "$platform"
4592                 ;;
4593             *)
4594                 usage
4595                 ;;
4596         esac
4597 .
4598 }
4599
4600 pp_backend_kit_function () {
4601     case "$1" in
4602         pp_mkgroup) cat <<'.';;
4603             grep "^$1:" /etc/group >/dev/null ||
4604                 /usr/sbin/groupadd $1
4605 .
4606         pp_mkuser) cat <<'.';;
4607             eval user=\$$#
4608             grep "^$user:" /etc/passwd >/dev/null ||
4609                 /usr/sbin/useradd -s /usr/bin/false "$@"
4610 .
4611         pp_havelib) cat <<'.';;
4612             for dir in `echo /usr/lib${3+:$3} | tr : ' '`; do
4613                 test -r "$dir/lib$1.${2-sl}" && return 0
4614             done
4615             return 1
4616 .
4617         *) pp_error "unknown function request: $1";;
4618     esac
4619 }
4620
4621 pp_backend_kit_init_svc_vars () {
4622     :
4623 }
4624
4625 pp_backend_kit_probe () {
4626     echo tru64-`uname -r | sed 's/V\([0-9]*\)\.\([0-9]*\)/\1\2/'`
4627 }
4628
4629 pp_kit_service_group_script () {
4630     typeset grp svcs scriptpath out
4631     grp="$1"
4632     svcs="$2"
4633     scriptpath="/sbin/init.d/$grp"
4634     out="$pp_destdir$scriptpath"
4635
4636     pp_add_file_if_missing $scriptpath run 755 || return 0
4637
4638     cat <<-. > $out
4639         #!/sbin/sh
4640         # generated by pp $pp_version
4641         svcs="$svcs"
4642 .
4643
4644 cat <<-'.' >> $out
4645         #-- starts services in order.. stops them all if any break
4646         pp_start () {
4647             undo=
4648             for svc in $svcs; do
4649                 /sbin/init.d/$svc start
4650                 case $? in
4651                     0|4)
4652                         undo="$svc $undo"
4653                         ;;
4654                     *)
4655                         if test -n "$undo"; then
4656                         for svc in $undo; do
4657                             /sbin/init.d/$svc stop
4658                         done
4659                         return 1
4660                         fi
4661                         ;;
4662                 esac
4663             done
4664             return 0
4665         }
4666
4667         #-- stops services in reverse
4668         pp_stop () {
4669             reverse=
4670                 for svc in $svcs; do
4671                     reverse="$svc $reverse"
4672                 done
4673                 rc=0
4674                 for svc in $reverse; do
4675                     /sbin/init.d/$svc stop || rc=$?
4676                 done
4677                 return $rc
4678         }
4679
4680         case $1 in
4681             start_msg) echo "Starting $svcs";;
4682         stop_msg)  echo "Stopping $svcs";;
4683         start)     pp_start;;
4684         stop)      pp_stop;;
4685         *)         echo "usage: $0 {start|stop|start_msg|stop_msg}"
4686             exit 1;;
4687         esac
4688 .
4689 }
4690
4691 pp_kit_service_script () {
4692     typeset svc scriptpath out
4693
4694     svc="$1"
4695     scriptpath="/sbin/init.d/$svc"
4696
4697     pp_load_service_vars "$svc"
4698
4699     test -n "$user" -a x"$user" != x"root" &&
4700     cmd="SHELL=/usr/bin/sh /usr/bin/su $user -c \"exec `echo $cmd | sed -e 's,[$\\\`],\\&,g'`\""
4701     if test -z "$pidfile"; then
4702         pidfile="/var/run/$svc.pid"
4703         cmd="$cmd & echo \$! > \$pidfile"
4704     fi
4705
4706     pp_add_file_if_missing $scriptpath run 755
4707
4708     cat <<-. > $pp_destdir$scriptpath
4709         svc="$svc"
4710         pidfile="$pidfile"
4711
4712         pp_start () {
4713             $cmd
4714         }
4715 .
4716     cat <<-'.' >>$pp_destdir$scriptpath
4717             pp_stop () {
4718                 if test ! -s "$pidfile"; then
4719                     echo "Unable to stop $svc (no pid file)"
4720                         return 1
4721                 else
4722                     read pid < "$pidfile"
4723                     if kill -0 "$pid" 2>/dev/null; then
4724                         if kill -${stop_signal:-TERM} "$pid"; then
4725                             rm -f "$pidfile"
4726                             return 0
4727                         else
4728                             echo "Unable to stop $svc"
4729                             return 1
4730                         fi
4731                     else
4732                         rm -f "$pidfile"
4733                         return 0
4734                     fi
4735                 fi
4736             }
4737
4738             pp_running () {
4739                 if test ! -s "$pidfile"; then
4740                     return 1
4741                 else
4742                     read pid < "$pidfile"
4743                     kill -0 "$pid" 2>/dev/null
4744                 fi
4745             }
4746             case $1 in
4747                 start_msg) echo "Starting the $svc service";;
4748                 stop_msg)  echo "Stopping the $svc service";;
4749                 start)
4750                     if pp_running; then
4751                         echo "$svc already running";
4752                         exit 0
4753                     elif pp_start; then
4754                         echo "$svc started";
4755         # rc(1M) says we should exit 4, but nobody expects it!
4756                         exit 0
4757                     else
4758                         exit 1
4759                     fi
4760                     ;;
4761                 stop)
4762                     if pp_stop; then
4763                         echo "$svc stopped";
4764                         exit 0
4765                     else
4766                         exit 1
4767                     fi
4768                     ;;
4769                 *) echo "usage: $0 {start|stop|start_msg|stop_msg}"
4770                    exit 1
4771                    ;;
4772             esac
4773 .
4774 }
4775
4776 pp_kit_make_service () {
4777     typeset level priority startlevels stoplevels
4778     typeset svc svcvar
4779
4780     svc="$1"
4781     svcvar=`pp_makevar $svc`
4782
4783     #-- don't do anything if the script exists
4784     if test -s "$pp_destdir/sbin/init.d/$svc"; then
4785         pp_error "$pp_destdir/sbin/init.d/$svc exists"
4786         return
4787     fi
4788
4789     # symlink the script, depending on the priorities chosen
4790     eval priority='${pp_kit_priority_'$svcvar'}'
4791     test -z "$priority" && priority="${pp_kit_priority:-50}"
4792
4793     eval startlevels='${pp_kit_startlevels_'$svcvar'}'
4794     test -z "$startlevels" && startlevels="$pp_kit_startlevels"
4795
4796     eval stoplevels='${pp_kit_stoplevels_'$svcvar'}'
4797     test -z "$stoplevels" && stoplevels="$pp_kit_stoplevels"
4798
4799     # create the script and config file
4800     pp_kit_service_script $svc
4801
4802     # fix the priority up
4803     case "$priority" in
4804         ???) :;;
4805         ??) priority=0$priority;;
4806         ?) priority=00$priority;;
4807     esac
4808
4809     if test x"$stoplevels" = x"auto"; then
4810         stoplevels=
4811         test -z "$startlevels" || for level in $startlevels; do
4812             stoplevels="$stoplevels `expr $level - 1`"
4813         done
4814     fi
4815
4816     # create the symlinks
4817     test -z "$startlevels" || for level in $startlevels; do
4818         echo "        ln -s /sbin/init.d/$svc /sbin/rc$level.d/S$priority$svc" >>$pp_wrkdir/%post.run
4819         echo "        rm /sbin/rc$level.d/S$priority$svc" >>$pp_wrkdir/%preun.run
4820     done
4821     test -z "$stoplevels" || for level in $stoplevels; do
4822         echo "        ln -s /sbin/init.d/$svc /sbin/rc$level.d/K$priority$svc" >>$pp_wrkdir/%post.run
4823         echo "        rm -f /sbin/rc$level.d/K$priority$svc" >>$pp_wrkdir/%preun.run
4824     done
4825 }
4826
4827
4828
4829
4830 pp_backend_kit_sizes () {
4831     awk '
4832     BEGIN { root = usr = var = 0; }
4833     {
4834         if (substr($9, 1, 1) != "l")
4835             if (substr($10, 1, 6) == "./var/")
4836                 var += $2;
4837             else if (substr($10, 1, 10) == "./usr/var/")
4838                 var += $2
4839             else if (substr($10, 1, 6) == "./usr/")
4840                 usr += $2
4841             else
4842                 root += $2
4843     }
4844     END { printf "%d\t%d\t%d", root, usr, var }
4845     ' "$@"
4846 }
4847
4848 pp_kit_kits_global () {
4849     line=`sed -n '/^%%/q;/^'$2'=/{s/^'$2'=//p;q;}' <"$1"`
4850     test -z "$line" && return 1
4851     eval "echo $line"
4852     :
4853 }
4854
4855 pp_backend_kit_kits () {
4856     typeset KITFILE FROMDIR TODIR
4857     typeset SCPDIR
4858
4859     SCPDIR="$pp_wrkdir/scps"
4860
4861     PATH="/usr/lbin:/usr/bin:/etc:/usr/ucb:$PATH"; export PATH # XXX
4862     #umask 2 # XXX
4863
4864     test $# -ge 3 || pp_die "pp_backend_kit_kits: too few arguments"
4865     KITFILE="$1"; shift
4866     FROMDIR="$1"; shift
4867     TODIR="$1"; shift
4868
4869     test -f "$KITFILE" || pp_die "$KITFILE not found"
4870     test -d "$FROMDIR" || pp_die "$FROMDIR not found"
4871     test -d "$TODIR"   || pp_die "$TODIR not found"
4872
4873     INSTCTRL="$TODIR/instctrl"
4874     mkdir -p "$INSTCTRL" || pp_die "cannot create instctrl directory"
4875     chmod 775 "$INSTCTRL"
4876
4877     grep "%%" $KITFILE > /dev/null || pp_die "no %% in $KITFILE"
4878
4879     typeset NAME CODE VERS MI ROOT COMPRESS
4880     typeset S_LIST ALLSUBS
4881
4882     NAME=`pp_kit_kits_global "$KITFILE" NAME` || pp_die "no NAME in $KITFILE"
4883     CODE=`pp_kit_kits_global "$KITFILE" CODE` || pp_die "no CODE in $KITFILE"
4884     VERS=`pp_kit_kits_global "$KITFILE" VERS` || pp_die "no VERS in $KITFILE"
4885     MI=`pp_kit_kits_global "$KITFILE" MI` || pp_die "no MI in $KITFILE"
4886     ROOT=`pp_kit_kits_global "$KITFILE" ROOT`
4887     COMPRESS=`pp_kit_kits_global "$KITFILE" COMPRESS`
4888
4889     test -f "$MI" || pp_die "Inventory file $MI not found"
4890
4891     case "$ROOT" in
4892     *ROOT)
4893         test -f "$TODIR/$ROOT" ||
4894             pp_die "Root image $ROOT not found in $TODIR" ;;
4895     esac
4896
4897     ALLSUBS=`awk 'insub==1 {print $1} /^%%/ {insub=1}' <"$KITFILE"`
4898     test $# -eq 0 && set -- $ALLSUBS
4899
4900     pp_debug "Creating $# $NAME subsets."
4901     pp_debug "ALLSUBS=<$ALLSUBS>"
4902
4903     if test x"$COMPRESS" = x"1"; then
4904         COMPRESS=:
4905     else
4906         COMPRESS=false
4907     fi
4908
4909     #rm -f *.ctrl Volume*
4910
4911     for SUB
4912     do
4913         test -z "$SUB" && pp_die "SUB is empty"
4914
4915         typeset INV CTRL ROOTSIZE USRSIZE VARSIZE TSSUB
4916         #rm -f Volume*
4917         case $SUB in
4918             .*) :;;
4919             *)  pp_verbose rm -f "$TODIR/$SUB"* "$INSTCTRL/$SUB"*;;
4920         esac
4921
4922         TSSUB="$pp_wrkdir/ts.$SUB"
4923
4924         pp_debug "kits: Subset $SUB"
4925
4926         INV="$SUB.inv"
4927         CTRL="$SUB.ctrl"
4928         pp_debug "kits: Generating media creation information..."
4929
4930         # Invcutter takes as input
4931         #   SUB dir/path
4932         # and generates stl_inv(4) files, like this
4933         #   f 0 00000 0 0 100644 2/11/09 010 f dir/path none SUB
4934         grep "  $SUB\$" "$MI" |
4935             pp_verbose /usr/lbin/invcutter \
4936                 -v "$VERS" -f "$FROMDIR" > "$INSTCTRL/$INV" ||
4937             pp_die "failed to create $INSTCTRL/$INV"
4938         chmod 664 "$INSTCTRL/$INV"
4939
4940         pp_backend_kit_sizes "$INSTCTRL/$INV" > "$pp_wrkdir/kit.sizes"
4941         read ROOTSIZE USRSIZE VARSIZE < "$pp_wrkdir/kit.sizes"
4942
4943         # Prefix each line with $FROMDIR. This will be stripped
4944         awk '$1 != "d" {print from $10}' from="$FROMDIR/" \
4945             > "$TSSUB" < "$INSTCTRL/$INV" ||
4946             pp_die "failed"
4947
4948         NVOLS=0
4949
4950         pp_debug "kits: Creating $SUB control file..."
4951
4952         sed '1,/^%%/d;/^'"$SUB"'/{p;q;}' < "$KITFILE" > "$pp_wrkdir/kit.line"
4953         read _SUB _IGNOR DEPS FLAGS DESC < "$pp_wrkdir/kit.line"
4954         if test -z "$_SUB"; then
4955             pp_warn "No such subset $SUB in $KITFILE"
4956             continue
4957         fi
4958         DEPS=`echo $DEPS | tr '|' ' '`
4959         case $FLAGS in
4960             FLGEXP*) pp_verbose FLAGS='"${'"$FLAGS"'}"' ;;
4961         esac
4962         case $DESC in
4963             *%*) DESC=`echo $DESC|awk -F% '{printf "%-36s%%%s\n", $1, $2}'`;;
4964         esac
4965
4966         cat > "$INSTCTRL/$CTRL" <<-.
4967                 NAME='$NAME $SUB'
4968                 DESC=$DESC
4969                 ROOTSIZE=$ROOTSIZE
4970                 USRSIZE=$USRSIZE
4971                 VARSIZE=$VARSIZE
4972                 NVOLS=1:$NVOLS
4973                 MTLOC=1:$TLOC
4974                 DEPS="$DEPS"
4975                 FLAGS=$FLAGS
4976 .
4977         chmod 664 "$INSTCTRL/$CTRL"
4978
4979         pp_debug "kits: Making tar image"
4980
4981         pp_verbose tar cfPR "$TODIR/$SUB" "$FROMDIR/" "$TSSUB" ||
4982              pp_error "problem creating kit file"
4983
4984         if $COMPRESS; then
4985             pp_debug "kits: Compressing"
4986             (cd "$TODIR" && compress -f -v "$SUB") ||
4987                 pp_die "problem compressing $TODIR/$SUB"
4988             SPC=`expr $SUB : '\(...\).*'`    # first three characters
4989             SVC=`expr $SUB : '.*\(...\)'`    # last three characters
4990             : > "$INSTCTRL/$SPC$SVC.comp"
4991             chmod 664 "$INSTCTRL/$SPC$SVC.comp"
4992             pp_debug "kits: Padding compressed file to 10kB" # wtf?
4993             rm -f "$TODIR/$SUB"
4994             pp_verbose \
4995             dd if="$TODIR/$SUB.Z" of="$TODIR/$SUB" bs=10k conv=sync ||
4996                 pp_die "problem moving compressed file"
4997             rm -f "$TODIR/$SUB.Z"
4998         fi
4999         chmod 664 "$TODIR/$SUB"
5000
5001         if test -f "$SCPDIR/$SUB.scp"; then
5002                 cp "$SCPDIR/$SUB.scp" "$INSTCTRL/$SUB.scp"
5003                 chmod 755 "$INSTCTRL/$SUB.scp"
5004         else
5005                 pp_debug "kits: null subset control program for $SUB"
5006                 : > "$INSTCTRL/$SUB.scp"
5007                 chmod 744 "$INSTCTRL/$SUB.scp"
5008         fi
5009
5010         pp_debug "kits: Finished creating media image for $SUB"
5011     done
5012
5013     pp_debug "kits: Creating $CODE.image"
5014
5015     case "$ROOT" in
5016     *ROOT)      ALLSUBS="$ROOT $ALLSUBS"
5017                 ;;
5018     esac
5019
5020     (cd "$TODIR" && sum $ALLSUBS) > "$INSTCTRL/$CODE.image"
5021     chmod 664 "$INSTTRL/$CODE.image"
5022     pp_debug "kits: Creating INSTCTRL"
5023     (cd "$INSTCTRL" && tar cpvf - *) > "$TODIR/INSTCTRL"
5024     chmod 664 "$TODIR/INSTCTRL"
5025     cp "$INSTCTRL/$CODE.image" "$TODIR/$CODE.image"
5026     chmod 664 "$TODIR/$CODE.image"
5027
5028     pp_debug "kits: Media image production complete"
5029 }
5030
5031 pp_platforms="$pp_platforms rpm"
5032
5033 pp_backend_rpm_detect () {
5034     test x"$1" = x"Linux" -a ! -f /etc/debian_version
5035 }
5036
5037 pp_backend_rpm_init () {
5038
5039     pp_rpm_version=
5040     pp_rpm_summary=
5041     pp_rpm_description=
5042     pp_rpm_group="Applications/Internet"
5043     pp_rpm_license="Unspecified"
5044     pp_rpm_vendor=
5045     pp_rpm_url=
5046     pp_rpm_packager=
5047     pp_rpm_provides=
5048     pp_rpm_requires=
5049     pp_rpm_release=
5050     pp_rpm_epoch=
5051     pp_rpm_dev_group="Development/Libraries"
5052     pp_rpm_dbg_group="Development/Tools"
5053     pp_rpm_doc_group="Documentation"
5054     pp_rpm_dev_description=
5055     pp_rpm_dbg_description=
5056     pp_rpm_doc_description=
5057     pp_rpm_dev_requires=
5058     pp_rpm_dbg_requires=
5059     pp_rpm_doc_requires=
5060     pp_rpm_dev_provides=
5061     pp_rpm_dbg_provides=
5062     pp_rpm_doc_provides=
5063
5064     pp_rpm_dbg_pkgname=debug
5065     pp_rpm_dev_pkgname=devel
5066     pp_rpm_doc_pkgname=doc
5067
5068     pp_rpm_defattr_uid=root
5069     pp_rpm_defattr_gid=root
5070
5071     pp_rpm_detect_arch
5072     pp_rpm_detect_distro
5073     pp_rpm_rpmbuild=`pp_rpm_detect_rpmbuild`
5074
5075     # SLES8 doesn't always come with readlink
5076     test -x /usr/bin/readlink -o -x /bin/readlink ||
5077         pp_readlink_fn=pp_ls_readlink
5078 }
5079
5080 pp_rpm_detect_arch () {
5081     pp_rpm_arch=auto
5082
5083     #-- Find the default native architecture that RPM is configured to use
5084     cat <<-. >$pp_wrkdir/dummy.spec
5085         Name: dummy
5086         Version: 1
5087         Release: 1
5088         Summary: dummy
5089         Group: ${pp_rpm_group}
5090         License: ${pp_rpm_license}
5091         %description
5092         dummy
5093 .
5094     $pp_opt_debug && cat $pp_wrkdir/dummy.spec
5095     pp_rpm_arch_local=`rpm -q --qf '%{arch}\n' --specfile $pp_wrkdir/dummy.spec`
5096     rm $pp_wrkdir/dummy.spec
5097
5098     #-- Ask the kernel what machine architecture is in use
5099     local arch=`uname -p`
5100     if [ "$arch" = "unknown" ]; then
5101         arch=`uname -m`
5102     fi
5103
5104     case "$arch" in
5105         i?86)   pp_rpm_arch_std=i386;;
5106         x86_64) pp_rpm_arch_std=x86_64;;
5107         ppc)    pp_rpm_arch_std=ppc;;
5108         ppc64)  pp_rpm_arch_std=ppc64;;
5109         ia64)   pp_rpm_arch_std=ia64;;
5110         s390)   pp_rpm_arch_std=s390;;
5111         s390x)  pp_rpm_arch_std=s390x;;
5112         powerpc)
5113                 # Probably AIX
5114                 case "`/usr/sbin/lsattr -El proc0 -a type -F value`" in
5115                     PowerPC_POWER*)     pp_rpm_arch_std=ppc64;;
5116                     *)                  pp_rpm_arch_std=ppc;;
5117                 esac
5118                 ;;
5119         *)      pp_rpm_arch_std=unknown;;
5120     esac
5121
5122     #-- Later on, when files are processed, we use 'file' to determine
5123     #   what platform ABIs are used. This is used when pp_rpm_arch == auto
5124     pp_rpm_arch_seen=
5125 }
5126
5127 pp_rpm_detect_distro () {
5128     pp_rpm_distro=
5129     if test -f /etc/whitebox-release; then
5130        pp_rpm_distro=`awk '
5131           /^White Box Enterprise Linux release/ { print "wbel" $6; exit; }
5132        ' /etc/whitebox-release`
5133     elif test -f /etc/fedora-release; then
5134        pp_rpm_distro=`awk '
5135           /^Fedora Core release/ { print "fc" $4; exit; }
5136           /^Fedora release/ { print "f" $3; exit; }
5137        ' /etc/fedora-release`
5138     elif test -f /etc/redhat-release; then
5139        pp_rpm_distro=`awk '
5140           /^Red Hat Enterprise Linux/ { print "rhel" $7; exit; }
5141           /^CentOS release/           { print "centos" $3; exit; }
5142           /^Red Hat Linux release/    { print "rh" $5; exit; }
5143        ' /etc/redhat-release`
5144     elif test -f /etc/SuSE-release; then
5145        pp_rpm_distro=`awk '
5146           /^SuSE Linux [0-9]/ { print "suse" $3; exit; }
5147           /^SUSE LINUX [0-9]/ { print "suse" $3; exit; }
5148           /^openSUSE [0-9]/   { print "suse" $2; exit; }
5149           /^S[uU]SE Linux Enterprise Server [0-9]/ { print "sles" $5; exit; }
5150           /^S[uU]SE LINUX Enterprise Server [0-9]/ { print "sles" $5; exit; }
5151           /^SuSE SLES-[0-9]/  { print "sles" substr($2,6); exit; }
5152        ' /etc/SuSE-release`
5153     elif test X"`uname -s 2>/dev/null`" = X"AIX"; then
5154         local r v
5155         r=`uname -r`
5156         v=`uname -v`
5157         pp_rpm_distro="aix$v$r"
5158     fi
5159     pp_rpm_distro=`echo $pp_rpm_distro | tr -d .`
5160     test -z "$pp_rpm_distro" &&
5161        pp_warn "unknown distro"
5162 }
5163
5164 pp_rpm_detect_rpmbuild () {
5165     local cmd
5166     for cmd in rpmbuild rpm; do
5167         if `which $cmd > /dev/null 2>&1`; then
5168             echo $cmd
5169             return 0
5170         fi
5171     done
5172
5173     pp_error "Could not find rpmbuild"
5174     # Default to `rpmbuild` in case it magically appears
5175     echo rpmbuild
5176     return 1
5177 }
5178
5179 pp_rpm_label () {
5180     local label arg
5181     label="$1"; shift
5182     for arg
5183     do
5184         test -z "$arg" || echo "$label: $arg"
5185     done
5186 }
5187
5188 pp_rpm_writefiles () {
5189     local _l t m o g f p st fo farch
5190     while read t m o g f p st; do
5191         _l="$p"
5192         test $t = d && _l="%dir ${_l%/}/"
5193         if test x"$m" = x"-"; then
5194             case "$t" in
5195                 d) m=755;;
5196                 f) m=644;;
5197             esac
5198         fi
5199         test x"$o" = x"-" && o="${pp_rpm_defattr_uid:-root}"
5200         test x"$g" = x"-" && g="${pp_rpm_defattr_gid:-root}"
5201         _l="%attr($m,$o,$g) $_l"
5202
5203         if test "$t" = "f" -a x"$pp_rpm_arch" = x"auto"; then
5204             fo=`file "${pp_destdir}$p" 2>/dev/null`
5205             #NB: The following should match executables and shared objects,
5206             #relocatable objects. It will not match .a files however.
5207             case "$fo" in
5208                 *": ELF 32-bit LSB "*", Intel 80386"*)
5209                     farch=i386;;
5210                 *": ELF 64-bit LSB "*", AMD x86-64"*|\
5211                 *": ELF 64-bit LSB "*", x86-64"*)
5212                     farch=x86_64;;
5213                 *": ELF 32-bit MSB "*", PowerPC"*)
5214                     farch=ppc;;
5215                 *": ELF 64-bit LSB "*", IA-64"*)
5216                     farch=ia64;;
5217                 *": ELF 32-bit MSB "*", IBM S/390"*)
5218                     farch=s390;;
5219                 *": ELF 64-bit MSB "*", IBM S/390"*)
5220                     farch=s390x;;
5221                 *"executable (RISC System/6000)"*)
5222                     farch=ppc;;
5223                 *"64-bit XCOFF executable"*)
5224                     fatch=ppc64;;
5225                 *)
5226                     farch=noarch;;
5227             esac
5228             pp_debug "file: $fo -> $farch"
5229             test x"$farch" = x"noarch" || pp_add_to_list pp_rpm_arch_seen $farch
5230         fi
5231
5232         case $f in *v*) _l="%config(noreplace) $_l";; esac
5233         echo "$_l"
5234     done
5235     echo
5236 }
5237
5238 pp_rpm_subname () {
5239     case "$1" in
5240         run) : ;;
5241         dbg) echo "${2}${pp_rpm_dbg_pkgname}";;
5242         dev) echo "${2}${pp_rpm_dev_pkgname}";;
5243         doc) echo "${2}${pp_rpm_doc_pkgname}";;
5244         *)   pp_error "unknown component '$1'";
5245     esac
5246 }
5247
5248 pp_rpm_depend () {
5249     while read _name _vers; do
5250         case "$_name" in ""| "#"*) continue ;; esac
5251         echo "Requires: $_name ${_vers:+>= $_vers}"
5252     done
5253 }
5254
5255 pp_rpm_override_requires () {
5256     local orig_find_requires
5257
5258     if test -z "$pp_rpm_depend_filter_cmd"; then
5259         return 0
5260     fi
5261
5262     orig_find_requires=`rpm --eval '%{__find_requires}'`
5263     cat << EOF > "$pp_wrkdir/filtered-find-requires"
5264 $orig_find_requires \$@ | $pp_rpm_depend_filter_cmd
5265 EOF
5266     chmod +x "$pp_wrkdir/filtered-find-requires"
5267     echo "%define __find_requires $pp_wrkdir/filtered-find-requires"
5268     # Might be necessary for old versions of RPM? Not for 4.4.2.
5269     #echo "%define _use_internal_dependency_generator 0"
5270 }
5271
5272 pp_backend_rpm () {
5273     local cmp specfile _summary _group _desc _pkg _subname svc
5274
5275         specfile=$pp_wrkdir/$name.spec
5276         : > $specfile
5277
5278         #-- force existence of a 'run' component
5279         pp_add_component run
5280         : >> $pp_wrkdir/%files.run
5281
5282         if test -z "$pp_rpm_arch"; then
5283             pp_error "Unknown RPM architecture"
5284             return 1
5285         fi
5286
5287         #-- Write the header components of the RPM spec file
5288         cat <<-. >>$specfile
5289                 Name: ${pp_rpm_name:-$name}
5290                 Version: ${pp_rpm_version:-$version}
5291                 Release: ${pp_rpm_release:-1}
5292                 Summary: ${pp_rpm_summary:-$summary}
5293                 Group:   ${pp_rpm_group}
5294                 License: ${pp_rpm_license}
5295 .
5296         if test -n "$pp_rpm_url"; then
5297             pp_rpm_label "URL"  "$pp_rpm_url"               >>$specfile
5298         fi
5299         pp_rpm_label "Vendor"   "${pp_rpm_vendor:-$vendor}" >>$specfile
5300         pp_rpm_label "Packager" "$pp_rpm_packager"          >>$specfile
5301         pp_rpm_label "Provides" "$pp_rpm_provides"          >>$specfile
5302         pp_rpm_label "Requires" "$pp_rpm_requires"          >>$specfile
5303
5304         test -n "$pp_rpm_serial" && pp_warn "pp_rpm_serial deprecated"
5305         if test -n "$pp_rpm_epoch"; then
5306             #-- Epoch was introduced in RPM 2.5.6
5307             case `$pp_rpm_rpmbuild --version 2>/dev/null` in
5308                 1.*|2.[0-5].*|2.5.[0-5])
5309                     pp_rpm_label "Serial" $pp_rpm_epoch >>$specfile;;
5310                 *)
5311                     pp_rpm_label "Epoch" $pp_rpm_epoch >>$specfile;;
5312             esac
5313         fi
5314
5315         if test -n "$pp_rpm_requires"; then
5316             pp_rpm_label "Requires" "$pp_rpm_requires" >>$specfile
5317         elif test -s $pp_wrkdir/%depend.run; then
5318             pp_rpm_depend < $pp_wrkdir/%depend.run >> $specfile
5319         fi
5320
5321         pp_rpm_override_requires >> $specfile
5322
5323         cat <<-. >>$specfile
5324
5325                 %description
5326                 ${pp_rpm_description:-$description}
5327 .
5328
5329         for cmp in $pp_components; do
5330                 case $cmp in
5331                    run) continue;;
5332                    dev) _summary="development tools for $pp_rpm_summary"
5333                         _group="$pp_rpm_dev_group"
5334                         _desc="${pp_rpm_dev_description:-Development libraries for $name. $pp_rpm_description.}"
5335                         ;;
5336                    doc) _summary="documentation for $pp_rpm_summary"
5337                         _group="$pp_rpm_doc_group"
5338                         _desc="${pp_rpm_doc_description:-Documentation for $name. $pp_rpm_description.}"
5339                         ;;
5340                    dbg) _summary="diagnostic tools for $pp_rpm_summary"
5341                         _group="$pp_rpm_dbg_group"
5342                         _desc="${pp_rpm_dbg_description:-Diagnostic tools for $name.}"
5343                         ;;
5344                 esac
5345
5346                 _subname=`pp_rpm_subname $cmp`
5347                 cat <<-.
5348
5349                         %package $_subname
5350                         Summary: $name $_summary
5351                         Group: $_group
5352 .
5353                 eval '_pkg="$pp_rpm_'$cmp'_requires"'
5354                 if test -n "$_pkg"; then
5355                     eval pp_rpm_label Requires ${pp_rpm_name:-$name} $_pkg
5356                 elif test -s $pp_wrkdir/%depend.$cmp; then
5357                     pp_rpm_depend < $pp_wrkdir/%depend.$cmp >> $specfile
5358                 fi
5359
5360                 eval '_pkg="$pp_rpm_'$cmp'_provides"'
5361                 eval pp_rpm_label Provides $_pkg
5362
5363                 cat <<-.
5364
5365                         %description $_subname
5366                         $_desc
5367 .
5368         done >>$specfile
5369
5370         #-- NB: we don't put any %prep, %build or %install RPM sections
5371         #   into the spec file.
5372
5373         #-- add service start/stop code
5374         if test -n "$pp_services"; then
5375             pp_rpm_service_install_common >> $pp_wrkdir/%post.run
5376
5377             #-- record the uninstall commands in reverse order
5378             for svc in $pp_services; do
5379                 pp_load_service_vars $svc
5380
5381                 pp_rpm_service_make_init_script $svc
5382
5383                 #-- append %post code to install the svc
5384                 pp_rpm_service_install $svc >> $pp_wrkdir/%post.run
5385
5386                 #-- prepend %preun code to uninstall svc
5387                 # (use files in case vars are modified)
5388                 pp_rpm_service_remove $svc | pp_prepend $pp_wrkdir/%preun.run
5389             done
5390             pp_rpm_service_remove_common | pp_prepend $pp_wrkdir/%preun.run
5391         fi
5392
5393         # make convenience service groups
5394         if test -n "$pp_service_groups"; then
5395             for grp in $pp_service_groups; do
5396                 pp_rpm_service_group_make_init_script \
5397                     $grp "`pp_service_get_svc_group $grp`"
5398             done
5399         fi
5400
5401         #-- Write the RPM %file sections
5402         #   (do this after services, since services adds to %files.run)
5403         for cmp in $pp_components; do
5404             _subname=`pp_rpm_subname $cmp`
5405
5406             if test -s $pp_wrkdir/%check.$cmp; then
5407                 echo ""
5408                 echo "%pre $_subname"
5409                 cat $pp_wrkdir/%check.$cmp
5410                 echo :   # causes script to exit true by default
5411             fi
5412
5413             if test -s $pp_wrkdir/%files.$cmp; then
5414                 echo ""
5415                 echo "%files $_subname"
5416                 pp_rpm_writefiles < $pp_wrkdir/%files.$cmp
5417             fi
5418
5419             if test -n "$pp_rpm_ghost"; then
5420                 for ghost in $pp_rpm_ghost; do
5421                     echo "%ghost $ghost"
5422                 done
5423             fi
5424
5425             if test -s $pp_wrkdir/%pre.$cmp; then
5426                 echo ""
5427                 echo "%pre $_subname"
5428                 cat $pp_wrkdir/%pre.$cmp
5429                 echo :   # causes script to exit true
5430             fi
5431
5432             if test -s $pp_wrkdir/%post.$cmp; then
5433                 echo ""
5434                 echo "%post $_subname"
5435                 cat $pp_wrkdir/%post.$cmp
5436                 echo :   # causes script to exit true
5437             fi
5438
5439             if test -s $pp_wrkdir/%preun.$cmp; then
5440                 echo ""
5441                 echo "%preun $_subname"
5442                 cat $pp_wrkdir/%preun.$cmp
5443                 echo :   # causes script to exit true
5444             fi
5445         done >>$specfile
5446
5447         #-- create a suitable work area for rpmbuild
5448         cat <<-. >$pp_wrkdir/.rpmmacros
5449                 %_topdir $pp_wrkdir
5450                 # XXX Note escaped %% for use in headerSprintf
5451                 %_rpmfilename   %%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
5452         .
5453         mkdir $pp_wrkdir/RPMS
5454         mkdir $pp_wrkdir/BUILD
5455
5456         if test x"$pp_rpm_arch" = x"auto"; then
5457             #-- Reduce the arch_seen list to exactly one item
5458             case "$pp_rpm_arch_seen" in
5459                 "i386 x86_64"|"x86_64 i386")
5460                     pp_rpm_arch_seen=x86_64;;
5461                 *"s390 s390x"* | *"s390x s390"* )
5462                     pp_rpm_arch_seen=s390x;;
5463                 *" "*)
5464                     pp_error "detected multiple targets: $pp_rpm_arch_seen"
5465                     pp_rpm_arch_seen=unknown;;      # not detected
5466                 "")
5467                     pp_warn "detected no binaries: using target noarch"
5468                     pp_rpm_arch_seen=noarch;;
5469                 *)
5470                     pp_debug "detected architecture $pp_rpm_arch_seen"
5471             esac
5472             pp_rpm_arch="$pp_rpm_arch_seen"
5473         fi
5474
5475         . $pp_wrkdir/%fixup
5476
5477 $pp_opt_debug && cat $specfile
5478
5479         pp_debug "creating: `pp_backend_rpm_names`"
5480
5481 pp_debug "pp_rpm_arch_seen = <${pp_rpm_arch_seen}>"
5482 pp_debug "pp_rpm_arch = <${pp_rpm_arch}>"
5483
5484         HOME=$pp_wrkdir \
5485         pp_verbose \
5486         $pp_rpm_rpmbuild -bb \
5487                 --buildroot="$pp_destdir/" \
5488                 --target="${pp_rpm_arch}" \
5489                 --define='_unpackaged_files_terminate_build 0' \
5490                 --define='_use_internal_dependency_generator 0' \
5491                 `$pp_opt_debug && echo --verbose || echo --quiet` \
5492                 $pp_rpm_rpmbuild_extra_flags \
5493                 $specfile ||
5494             pp_error "Problem creating RPM packages"
5495
5496         for f in `pp_backend_rpm_names`; do
5497             # The package might be in an arch-specific subdir
5498             pkgfile=not-found
5499             for dir in $pp_wrkdir/RPMS/${pp_rpm_arch} $pp_wrkdir/RPMS; do
5500                 if test -f $dir/$f; then
5501                     pkgfile=$dir/$f
5502                 fi
5503             done
5504             if test x"$pkgfile" = x"not-found"; then
5505                 pp_error "Problem predicting RPM filename: $f"
5506             else
5507                 ln $pkgfile $pp_wrkdir/$f
5508             fi
5509         done
5510 }
5511
5512 pp_rpm_output_name () {
5513     echo "${pp_rpm_name:-$name}`pp_rpm_subname "$1" -`-${pp_rpm_version:-$version}-${pp_rpm_release:-1}.${pp_rpm_arch}.rpm"
5514 }
5515
5516 pp_backend_rpm_names () {
5517     local cmp _subname
5518     for cmp in $pp_components; do
5519         pp_rpm_output_name $cmp
5520     done
5521 }
5522
5523 pp_backend_rpm_cleanup () {
5524     :
5525 }
5526
5527 pp_rpm_print_requires () {
5528     local _subname _name
5529
5530     echo "CPU:$pp_rpm_arch"
5531     ## XXX should be lines of the form (from file/ldd/objdump)
5532     #    EXEC:/bin/sh
5533     #    RTLD:libc.so.4:open
5534     rpm -q --requires -p $pp_wrkdir/`pp_rpm_output_name $1` |sed -e '/^rpmlib(/d;s/ //g;s/^/RPM:/' | sort -u
5535 }
5536
5537 pp_backend_rpm_install_script () {
5538     local cmp _subname
5539
5540     echo "#!/bin/sh"
5541     pp_install_script_common
5542
5543     cat <<.
5544
5545         cmp_to_pkgname () {
5546             local oi name
5547             if test x"\$1" = x"--only-installed"; then
5548                 #-- only print if installation detected
5549                 oi=false
5550                 shift
5551             else
5552                 oi=true
5553             fi
5554             test x"\$*" = x"all" &&
5555                 set -- $pp_components
5556             for cmp
5557             do
5558                 case \$cmp in
5559 .
5560     for cmp in $pp_components; do
5561         _subname=`pp_rpm_subname $cmp -`
5562          echo "$cmp) name=${pp_rpm_name:-$name}${_subname};;"
5563     done
5564     cat <<.
5565                 *) usage;;
5566                 esac
5567                 if \$oi || rpm -q "\$name" >/dev/null 2>/dev/null; then
5568                     echo "\$name"
5569                 fi
5570             done
5571         }
5572
5573
5574         cmp_to_pathname () {
5575             test x"\$*" = x"all" &&
5576                 set -- $pp_components
5577             for cmp
5578             do
5579                 case \$cmp in
5580 .
5581     for cmp in $pp_components; do
5582         echo "$cmp) echo \${PP_PKGDESTDIR:-.}/`pp_rpm_output_name $cmp` ;;"
5583     done
5584     cat <<.
5585                 *) usage;;
5586                 esac
5587             done
5588         }
5589
5590         print_requires () {
5591             test x"\$*" = x"all" &&
5592                 set -- $pp_components
5593             for cmp
5594             do
5595                 case \$cmp in
5596 .
5597     for cmp in $pp_components; do
5598         echo "$cmp) cat <<'._end'"
5599         pp_rpm_print_requires $cmp
5600         echo "._end"; echo ';;'
5601     done
5602     cat <<.
5603                 *) usage;;
5604                 esac
5605             done
5606         }
5607
5608         test \$# -eq 0 && usage
5609         op="\$1"; shift
5610         case "\$op" in
5611             list-components)
5612                 test \$# -eq 0 || usage \$op
5613                 echo $pp_components
5614                 ;;
5615             list-services)
5616                 test \$# -eq 0 || usage \$op
5617                 echo $pp_services
5618                 ;;
5619             list-files)
5620                 test \$# -ge 1 || usage \$op
5621                 cmp_to_pathname "\$@"
5622                 ;;
5623             install)
5624                 test \$# -ge 1 || usage \$op
5625                 verbose rpm -U --replacepkgs --oldpackage \
5626                     \`cmp_to_pathname "\$@"\`
5627                 ;;
5628             uninstall)
5629                 test \$# -ge 1 || usage \$op
5630                 pkgs=\`cmp_to_pkgname --only-installed "\$@"\`
5631                 if test -z "\$pkgs"; then
5632                     verbosemsg "nothing to uninstall"
5633                 else
5634                     verbose rpm -e \$pkgs
5635                 fi
5636                 ;;
5637             start|stop)
5638                 test \$# -ge 1 || usage \$op
5639                 ec=0
5640                 for svc
5641                 do
5642                     verbose /etc/init.d/\$svc \$op || ec=1
5643                 done
5644                 exit \$ec
5645                 ;;
5646             print-platform)
5647                 test \$# -eq 0 || usage \$op
5648                 echo "linux-${pp_rpm_arch}"
5649                 ;;
5650             print-requires)
5651                 test \$# -ge 1 || usage \$op
5652                 print_requires "\$@"
5653                 ;;
5654             *)
5655                 usage
5656                 ;;
5657         esac
5658 .
5659
5660 }
5661
5662 pp_backend_rpm_probe () {
5663         echo "${pp_rpm_distro}-${pp_rpm_arch_std}"
5664 }
5665
5666 pp_backend_rpm_vas_platforms () {
5667     case "$pp_rpm_arch_std" in
5668         x86_64) echo "linux-x86_64.rpm linux-x86.rpm";;
5669         *86)    echo "linux-x86.rpm";;
5670         s390)   echo "linux-s390";;
5671         s390x)  echo "linux-s390x";;
5672         ppc*)   echo "linux-glibc23-ppc64 linux-glibc22-ppc64";;
5673         ia64)   echo "linux-ia64";;
5674         *)      pp_die "unknown architecture $pp_rpm_arch_std";;
5675     esac
5676 }
5677
5678 pp_backend_rpm_init_svc_vars () {
5679     pp_rpm_default_start_runlevels="2 3 4 5"
5680     pp_rpm_default_svc_description="No description"
5681 }
5682
5683 pp_rpm_service_install_common () {
5684     cat <<-'.'
5685
5686         _pp_install_service () {
5687             local svc level
5688             svc="$1"
5689             if [ -x /usr/lib/lsb/install_initd -a ! -r /etc/redhat-release ]
5690             then
5691                 # LSB-style install
5692                 /usr/lib/lsb/install_initd /etc/init.d/$svc &> /dev/null
5693             elif [ -x /sbin/chkconfig ]; then
5694                 # Red Hat/chkconfig-style install
5695                 /sbin/chkconfig --add $svc &> /dev/null
5696                 /sbin/chkconfig $svc off &> /dev/null
5697             else
5698                 : # manual links under /etc/init.d
5699             fi
5700         }
5701
5702         _pp_enable_service () {
5703             local svc level
5704             svc="$1"
5705             if [ -x /usr/lib/lsb/install_initd -a ! -r /etc/redhat-release ]
5706             then
5707                 # LSB-style install
5708                 : # not sure how to enable
5709             elif [ -x /sbin/chkconfig ]; then
5710                 # Red Hat/chkconfig-style install
5711                 /sbin/chkconfig $svc on &> /dev/null
5712             else
5713                 # manual install
5714                 set -- `sed -n -e 's/^# Default-Start://p' /etc/init.d/$svc`
5715                 start_priority=`sed -n -e 's/^# X-Quest-Start-Priority:[[:space:]]*//p' /etc/init.d/$svc`
5716                 stop_priority=`sed -n -e 's/^# X-Quest-Stop-Priority:[[:space:]]*//p' /etc/init.d/$svc`
5717
5718                 # Provide default start & stop priorities of 20 & 80 in
5719                 # accordance with Debian update-rc.d defaults
5720                 if [ -z "$start_priority" ]; then
5721                     start_priority=20
5722                 fi
5723                 if [ -z "$stop_priority" ]; then
5724                     stop_priority=80
5725                 fi
5726                     
5727                 if [ -d "/etc/rc.d" ];then
5728                     rcdir=/etc/rc.d
5729                 else
5730                     rcdir=/etc
5731                 fi
5732
5733                 for level
5734                 do ln -sf /etc/init.d/$svc $rcdir/rc$level.d/S$start_priority$svc; done
5735                 set -- `sed -n -e 's/^# Default-Stop://p' /etc/init.d/$svc`
5736                 for level
5737                 do ln -sf /etc/init.d/$svc $rcdir/rc$level.d/K$stop_priority$svc; done
5738             fi
5739         }
5740 .
5741 }
5742
5743 pp_rpm_service_remove_common () {
5744     cat <<-'.'
5745
5746         _pp_remove_service () {
5747             local svc
5748             svc="$1"
5749             /etc/init.d/$svc stop >/dev/null 2>&1
5750             if [ -x /usr/lib/lsb/remove_initd -a ! -r /etc/redhat-release ]
5751             then
5752                 /usr/lib/lsb/remove_initd /etc/init.d/$svc &> /dev/null
5753             elif [ -x /sbin/chkconfig ]; then
5754                 /sbin/chkconfig --del $svc &> /dev/null
5755             else
5756                 if [ -d "/etc/rc.d" ];then
5757                     rcdir=/etc/rc.d
5758                 else
5759                     rcdir=/etc
5760                 fi
5761
5762                 rm -f $rcdir/rc?.d/[SK]??$svc
5763             fi
5764         }
5765 .
5766 }
5767
5768
5769 pp_rpm_service_install () {
5770     pp_rpm_service_make_init_script $1 >/dev/null ||
5771         pp_error "could not create init script for service $1"
5772     echo "_pp_install_service $1"
5773     test $enable = yes && echo "_pp_enable_service $1"
5774 }
5775
5776 pp_rpm_service_remove () {
5777     cat <<-.
5778         if [ "\$1" = "remove" -o "\$1" = "0" ]; then
5779             # only remove the service if not upgrade
5780             _pp_remove_service $1
5781         fi
5782 .
5783 }
5784
5785
5786 pp_backend_rpm_init_svc_vars () {
5787
5788     reload_signal=
5789     start_runlevels=${pp_rpm_default_start_runlevels}   # == lsb default-start
5790     stop_runlevels="0 1 6"                              # == lsb default-stop
5791     svc_description="${pp_rpm_default_svc_description}" # == lsb short descr
5792     svc_process=
5793
5794     lsb_required_start='$local_fs $network'
5795     lsb_should_start=
5796     lsb_required_stop=
5797     lsb_description=
5798
5799     start_priority=50
5800     stop_priority=50            #-- stop_priority = 100 - start_priority
5801 }
5802
5803 pp_rpm_service_group_make_init_script () {
5804     local grp=$1
5805     local svcs="$2"
5806     local script=/etc/init.d/$grp
5807     local out=$pp_destdir$script
5808
5809     pp_add_file_if_missing $script run 755 || return 0
5810
5811     cat <<-. >>$out
5812         #!/bin/sh
5813         svcs="$svcs"
5814 .
5815
5816     cat <<-'.' >>$out
5817
5818         #-- prints usage message
5819         pp_usage () {
5820             echo "usage: $0 {start|stop|status|restart|reload|condrestart|try-restart|force-reload}" >&2
5821             return 2
5822         }
5823
5824         #-- starts services in order.. stops them all if any break
5825         pp_start () {
5826             undo=
5827             for svc in $svcs; do
5828                 if /etc/init.d/$svc start; then
5829                     undo="$svc $undo"
5830                 else
5831                     if test -n "$undo"; then
5832                         for svc in $undo; do
5833                            /etc/init.d/$svc stop
5834                         done
5835                         return 1
5836                     fi
5837                 fi
5838             done
5839             return 0
5840         }
5841
5842         #-- stops services in reverse
5843         pp_stop () {
5844             reverse=
5845             for svc in $svcs; do
5846                 reverse="$svc $reverse"
5847             done
5848             rc=0
5849             for svc in $reverse; do
5850                 /etc/init.d/$svc stop || rc=$?
5851             done
5852             return $rc
5853         }
5854
5855         #-- returns true only if all services return true status
5856         pp_status () {
5857             rc=0
5858             for svc in $svcs; do
5859                 /etc/init.d/$svc status || rc=$?
5860             done
5861             return $rc
5862         }
5863
5864         pp_reload () {
5865             rc=0
5866             for svc in $svcs; do
5867                 /etc/init.d/$svc reload || rc=$?
5868             done
5869             return $rc
5870         }
5871
5872         case "$1" in
5873             start)          pp_start;;
5874             stop)           pp_stop;;
5875             restart)        pp_stop; pp_start;;
5876             status)         pp_status;;
5877             try-restart|condrestart)
5878                             if pp_status >/dev/null; then
5879                                     pp_restart
5880                             fi;;
5881             reload)         pp_reload;;
5882             force-reload)   if pp_status >/dev/null; then
5883                                     pp_reload
5884                             else
5885                                     pp_restart
5886                             fi;;
5887             *)              pp_usage;;
5888         esac
5889 .
5890     chmod 755 $out
5891 }
5892
5893 pp_rpm_service_make_init_script () {
5894     local svc=$1
5895     local script=/etc/init.d/$svc
5896     local out=$pp_destdir$script
5897     local _process _cmd _rpmlevels
5898
5899     pp_add_file_if_missing $script run 755 || return 0
5900
5901     #-- start out as an empty shell script
5902     cat <<-'.' >$out
5903         #!/bin/sh
5904 .
5905
5906     #-- determine the process name from $cmd unless $svc_process is given
5907     set -- $cmd
5908     _process=${svc_process:-"$1"}
5909
5910     #-- construct a start command that builds a pid file if needed
5911     _cmd="$cmd";
5912     if test -z "$pidfile"; then
5913         pidfile=/var/run/$svc.pid
5914         _cmd="$cmd & echo \$! > \$pidfile"
5915     fi
5916     if test "$user" != "root"; then
5917         _cmd="su $user -c exec $_cmd";
5918     fi
5919
5920     #-- generate the Red Hat chkconfig headers
5921     _rpmlevels=`echo $start_runlevels | tr -d ' '`
5922     cat <<-. >>$out
5923         # chkconfig: ${_rpmlevels:--} ${start_priority:-50} ${stop_priority:-50}
5924         # description: ${svc_description:-no description}
5925         # processname: ${_process}
5926         # pidfile: ${pidfile}
5927 .
5928
5929     #-- generate the LSB init info
5930     cat <<-. >>$out
5931         ### BEGIN INIT INFO
5932         # Provides: ${svc}
5933         # Required-Start: ${lsb_required_start}
5934         # Should-Start: ${lsb_should_start}
5935         # Required-Stop: ${lsb_required_stop}
5936         # Default-Start: ${start_runlevels}
5937         # Default-Stop: ${stop_runlevels}
5938         # Short-Description: ${svc_description}
5939         ### END INIT INFO
5940         # Generated by PolyPackage ${pp_version}
5941         # ${copyright}
5942
5943 .
5944
5945     if test x"${svc_description}" = x"${pp_rpm_default_svc_description}"; then
5946         svc_description=
5947     fi
5948
5949     #-- write service-specific definitions
5950     cat <<. >>$out
5951         #-- definitions specific to service ${svc}
5952         svc_name="${svc_description:-$svc service}"
5953         user="${user}"
5954         pidfile="${pidfile}"
5955         stop_signal="${stop_signal}"
5956         reload_signal="${reload_signal}"
5957         pp_exec_cmd () { $_cmd; }
5958 .
5959
5960     #-- write the generic part of the init script
5961     cat <<'.' >>$out
5962
5963         #-- use system message logging, if available
5964         if [ -f /lib/lsb/init-functions -a ! -r /etc/redhat-release ]; then
5965             . /lib/lsb/init-functions
5966             pp_success_msg () { log_success_msg "$@"; }
5967             pp_failure_msg () { log_failure_msg "$@"; }
5968             pp_warning_msg () { log_warning_msg "$@"; }
5969         elif [ -f /etc/init.d/functions ]; then
5970             . /etc/init.d/functions
5971             pp_success_msg () { echo -n "$*"; success "$@"; echo; }
5972             pp_failure_msg () { echo -n "$*"; failure "$@"; echo; }
5973             pp_warning_msg () { echo -n "$*"; warning "$@"; echo; }
5974         else
5975             pp_success_msg () { echo ${1:+"$*:"} OK; }
5976             pp_failure_msg () { echo ${1:+"$*:"} FAIL; }
5977             pp_warning_msg () { echo ${1:+"$*:"} WARNING; }
5978         fi
5979
5980         #-- prints a status message
5981         pp_msg () { echo -n "$*: "; }
5982
5983         #-- prints usage message
5984         pp_usage () {
5985             echo "usage: $0 {start|stop|status|restart|reload|condrestart|try-restart|force-reload}" >&2
5986             return 2
5987         }
5988
5989         #-- reloads the service, if possible
5990         #   returns 0=success 1=failure 3=unimplemented
5991         pp_reload () {
5992             test -n "$reload_signal" || return 3 # unimplemented
5993             pp_msg "Reloading ${svc_name}"
5994             if pp_signal -${reload_signal}; then
5995                 pp_success_msg
5996                 return 0
5997             else
5998                 pp_failure_msg "not running"
5999                 return 1
6000             fi
6001         }
6002
6003         #-- delivers signal $1 to the pidfile
6004         #   returns 0=success 1=failure
6005         pp_signal () {
6006             if test -r "$pidfile"; then
6007                 read pid < $pidfile
6008                 kill "$@" "$pid" 2>/dev/null
6009             else
6010                 return 1
6011             fi
6012         }
6013
6014         #-- prints information about the service status
6015         #   returns 0=running 1=crashed 3=stopped
6016         pp_status () {
6017             pp_msg "Checking for ${svc_name}"
6018             if pp_signal -0; then
6019                 pp_success_msg "running"
6020                 return 0
6021             elif test -r "$pidfile"; then
6022                 pp_failure_msg "not running (crashed)"
6023                 return 1
6024             else
6025                 pp_failure_msg "not running"
6026                 return 3
6027             fi
6028         }
6029
6030         #-- starts the service
6031         #   returns 0=success 1=failure
6032         pp_start () {
6033             pp_msg "Starting ${svc_name}"
6034             if pp_status >/dev/null; then
6035                 pp_warning_msg "already started"
6036                 return 0
6037             elif pp_exec_cmd; then
6038                 pp_success_msg
6039                 return 0
6040             else
6041                 pp_failure_msg "cannot start"
6042                 return 1
6043             fi
6044         }
6045
6046         #-- stops the service
6047         #   returns 0=success (always)
6048         pp_stop () {
6049             pp_msg "Stopping ${svc_name}"
6050             if pp_signal -${stop_signal}; then
6051                 pp_success_msg
6052             else
6053                 pp_success_msg "already stopped"
6054             fi
6055             rm -f "$pidfile"
6056             return 0
6057         }
6058
6059         #-- stops and starts the service
6060         pp_restart () {
6061             pp_stop
6062             pp_start
6063         }
6064
6065         case "$1" in
6066             start)          pp_start;;
6067             stop)           pp_stop;;
6068             restart)        pp_restart;;
6069             status)         pp_status;;
6070             try-restart|condrestart)
6071                             if pp_status >/dev/null; then
6072                                     pp_restart
6073                             fi;;
6074             reload)         pp_reload;;
6075             force-reload)   if pp_status >/dev/null; then
6076                                     pp_reload
6077                             else
6078                                     pp_restart
6079                             fi;;
6080             *)              pp_usage;;
6081         esac
6082
6083 .
6084     chmod 755 $out
6085 }
6086 pp_backend_rpm_function () {
6087     case $1 in
6088         pp_mkgroup) cat<<'.';;
6089             /usr/sbin/groupadd -f -r "$1"
6090 .
6091         pp_mkuser:depends) echo pp_mkgroup;;
6092         pp_mkuser) cat<<'.';;
6093             pp_mkgroup "${2:-$1}" || return 1
6094             /usr/sbin/useradd \
6095                 -g "${2:-$1}" \
6096                 -M -d "${3:-/nonexistent}" \
6097                 -s "${4:-/bin/false}" \
6098                 -r "$1"
6099 .
6100         pp_havelib) cat<<'.';;
6101             for pp_tmp_dir in `echo "/usr/lib:/lib${3:+:$3}" | tr : ' '`; do
6102                 test -r "$pp_tmp_dir/lib$1.so{$2:+.$2}" && return 0
6103             done
6104             return 1
6105 .
6106         *) false;;
6107     esac
6108 }
6109
6110 : NOTES <<.
6111
6112  # creating a dmg file for publishing on the web
6113     hdiutil create -srcfolder /path/foo foo.dmg
6114     hdiutil internet-enable -yes /path/foo.dmg
6115  # Layout for packages
6116     <name>-<cpy>/component/<file>
6117     <name>-<cpt>/extras/postinstall
6118     <name>-<cpt>/extras/postupgrade
6119  # /Developer/usr/bin/packagemaker (man packagemaker)
6120
6121     Make a bunch of packages, and then build a 'distribution'
6122     which is only understood by macos>10.4
6123
6124  # Message files in the resource path used are
6125     Welcome.{rtf,html,rtfd,txt} - limited text shown in Intro
6126     ReadMe.{rtf,html,rtfd,txt} - scrollable/printable, after Intro
6127     License.{rtf,html,rtfd,txt} - ditto, user must click 'Accept'
6128     background.{jpg,tif,gif,pict,eps,pdf} 620x418 background image
6129
6130  # These scripts looked for in the resource path
6131     InstallationCheck $pkgpath $defaultloc $targetvol
6132         0:ok 32:warn 32+x:warn[1] 64:stop 96+x:stop[2]
6133     VolumeCheck $volpath
6134         0:ok 32:failure 32+x:failure[3]
6135     preflight   $pkgpath $targetloc $targetvol    [priv]
6136     preinstall  $pkgpath $targetloc $targetvol    [priv]
6137     preupgrade  $pkgpath $targetloc $targetvol    [priv]
6138     postinstall $pkgpath $targetloc $targetvol    [priv]
6139     postupgrade $pkgpath $targetloc $targetvol    [priv]
6140     postflight  $pkgpath $targetloc $targetvol    [priv]
6141         0:ok else fail (for all scripts)
6142
6143     A detailed reason is deduced by finding an index x (16..31)
6144     in the file InstallationCheck.strings or VolumeCheck.strings.
6145
6146     Scripts marked [priv] are executed with root privileges.
6147     None of the [priv] scripts are used by metapackages.
6148
6149  # Default permissions
6150     Permissions of existing directories should match those
6151     of a clean install of the OS; typically root:admin 0775
6152     New directories or files should be 0775 or 0664 with the
6153     appropriate user:group.
6154     Exceptions:
6155         /etc    root:admin 0755
6156         /var    root:admin 0755
6157
6158     <http://developer.apple.com/documentation/DeveloperTools/Conceptual/SoftwareDistribution4/Concepts/sd_pkg_flags.html>
6159     Info.plist = {
6160      CFBundleGetInfoString: "1.2.3, Quest Software, Inc.",
6161      CFBundleIdentifier: "com.quest.rc.openssh",
6162      CFBundleShortVersionString: "1.2.3",
6163      IFMajorVersion: 1,
6164      IFMinorVersion: 2,
6165      IFPkgFlagAllowBackRev: false,
6166      IFPkgFlagAuthorizationAction: "AdminAuthorization",
6167      IFPkgFlagDefaultLocation: "/",
6168      IFPkgFlagFollowLinks: true,
6169      IFPkgFlagInstallFat: false,
6170      IFPkgFlagInstalledSize: <integer>,     # this is added by packagemaker
6171      IFPkgFlagIsRequired: false,
6172      IFPkgFlagOverwritePermissions: false,
6173      IFPkgFlagRelocatable: false,
6174      IFPkgFlagRestartAction: "NoRestart",
6175      IFPkgFlagRootVolumeOnly: false,
6176      IFPkgFlagUpdateInstalledLanguages: false,
6177      IFPkgFormatVersion= 0.10000000149011612,
6178      IFRequirementDicts: [ {
6179        Level = "requires",
6180        SpecArgument = "/opt/quest/lib/libvas.4.2.0.dylib",
6181        SpecType = "file",
6182        TestObject = true,
6183        TestOperator = "eq", } ]
6184     }
6185
6186     Description.plist = {
6187      IFPkgDescriptionDescription = "this is the description text",
6188      IFPkgDescriptionTitle = "quest-openssh"
6189     }
6190
6191  # Startup scripts
6192     'launchd' is a kind of combined inetd and rc/init.d system.
6193     <http://developer.apple.com/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/DesigningDaemons.html>
6194     Create a /Library/LaunchDaemons/$daemonname.plist file
6195     Examples found in /System/Library/LaunchDaemons/
6196     See manual page launchd.plist(5) for details:
6197
6198     { Label: "com.quest.vintela.foo",                        # required
6199       Program: "/sbin/program",
6200       ProgramArguments: [ "/sbin/program", "arg1", "arg2" ], # required
6201       RunAtLoad: true,
6202       WatchPaths: [ "/etc/crontab" ],
6203       QueueDirectories: [ "/var/cron/tabs" ],
6204       inetdCompatibility: { Wait: false },                   # inetd-only
6205       OnDemand: false,                                       # recommended
6206       SessionCreate: true,
6207       UserName: "nobody",
6208       InitGroups: true,
6209       Sockets: {                                             # inetd only
6210         Listeners: {
6211            SockServiceName: "ssh",
6212            Bonjour: ["ssh", "sftp-ssh"], } },
6213       Disabled: false,
6214       StandardErrorPath: "/dev/null",
6215     }
6216
6217
6218     How to add a new user
6219         dscl . -create /Users/$user
6220         dscl . -create /Users/$user UserShell /bin/bash
6221         dscl . -create /Users/$user RealName "$user"
6222         dscl . -create /Users/$user UniqueID $uid
6223         dscl . -create /Users/$user PrimaryGroupID $gid
6224         dscl . -create /Users/$user NFSHomeDirectory /Users/$user
6225         dscl . -passwd /Users/$user "$passwd"
6226         mkdir /Users/$user
6227         chown $uid.$gid /Users/$user
6228
6229 .
6230
6231
6232 pp_platforms="$pp_platforms macos"
6233
6234 pp_backend_macos_detect () {
6235     [ x"$1" = x"Darwin" ]
6236 }
6237
6238 pp_backend_macos_init () {
6239     pp_macos_default_bundle_id_prefix="com.quest.rc."
6240     pp_macos_bundle_id=
6241     pp_macos_bundle_vendor=
6242     pp_macos_bundle_version=
6243     pp_macos_bundle_info_string=
6244     pp_macos_prog_packagemaker=/Developer/usr/bin/packagemaker
6245     pp_macos_pkg_domain=anywhere
6246     pp_macos_pkg_extra_flags=
6247 }
6248
6249 pp_macos_plist () {
6250     typeset in
6251     in=""
6252     while test $# -gt 0; do
6253      case "$1" in
6254
6255       start-plist) cat <<-.; in="  "; shift ;;
6256         <?xml version="1.0" encoding="UTF-8"?>
6257         <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
6258         <plist version="1.0">
6259 .
6260       end-plist) echo "</plist>"; in=; shift;;
6261
6262       '[')   echo "$in<array>"; in="$in  "; shift;;
6263       ']')   echo "$in</array>"; in="${in#  }"; shift;;
6264       '{')   echo "<dict>"; in="$in      "; shift;;
6265       '}')   echo "</dict>"; in="${in#      }"; shift;;
6266       key)         shift; echo "$in<key>$1</key>"; shift;;
6267       string)      shift;
6268                    echo "$1" | sed -e 's/&/&amp;/g;s/</\&lt;/g;s/>/\&gt;/g;' \
6269                                    -e 's/^/'"$in"'<string>/;s/$/<\/string>/';
6270                    shift;;
6271       true)        echo "$in<true/>"; shift;;
6272       false)       echo "$in<false/>"; shift;;
6273       real)        shift; echo "$in<real>$1</real>"; shift;;
6274       integer)     shift; echo "$in<integer>$1</integer>"; shift;;
6275       date)        shift; echo "$in<date>$1</date>"; shift;; # ISO 8601 format
6276       data)        shift; echo "$in<data>$1</data>"; shift;; # base64 encoded
6277       *)           pp_error "pp_macos_plist: bad argument '$1'"; shift;;
6278      esac
6279     done
6280 }
6281
6282 pp_macos_rewrite_cpio () {
6283     typeset script
6284     script=$pp_wrkdir/cpio-rewrite.pl
6285     # rely on the fact that OS X comes with perl. It is a little easier to
6286     # re-write a binary stream with perl than it is with posix :)
6287     #
6288     # A CPIO header block has octal fields at the following offset/lengths:
6289     #   0  6 magic
6290     #   6  6 dev
6291     #  12  6 ino
6292     #  18  6 mode
6293     #  24  6 uid
6294     #  30  6 gid
6295     #  36  6 nlink
6296     #  42  6 rdev
6297     #  48 11 mtime
6298     #  59  6 namesize
6299     #  65 11 filesize
6300     #  76    --
6301     cat <<-'.' >$script
6302         while (<DATA>) {
6303                 my ($type,$mode,$uid,$gid,$flags,$name) =
6304                     m/^(.) (\d+) (\S+) (\S+) (\S+) (.*)/;
6305                 $uid = 0 if $uid eq "-";
6306                 $gid = 0 if $gid eq "-";
6307                 if ($uid ne "=" and $uid =~ m/\D/) {
6308                         my @pw = getpwnam($uid) or die "bad username '$uid'";
6309                         $uid = $pw[2];
6310                 }
6311                 if ($gid ne "=" and $gid =~ m/\D/) {
6312                         my @gr = getgrnam($gid) or die "bad group '$gid'";
6313                         $gid = $gr[2];
6314                 }
6315                 $name = ".".$name."\0";
6316                 $ok{$name} = 1;
6317                 $uid{$name} = sprintf("%06o",int($uid)) unless $uid eq "=";
6318                 $gid{$name} = sprintf("%06o",int($gid)) unless $gid eq "=";
6319                 $mode{$name} = sprintf("%06o",oct($mode)) unless $mode eq "=";
6320         }
6321         $ok{"TRAILER!!!\0"} = 1;
6322         while (!eof STDIN) {
6323                 read STDIN, $header, 76;
6324                 die "bad magic" unless $header =~ m/^070707/;
6325                 $namesize = oct(substr($header,59,6));
6326                 $filesize = oct(substr($header,65,11));
6327                 read STDIN, $name, $namesize;
6328                 # convert uid and gid to 0
6329                 substr($header, 24, 6) = $uid{$name} if defined($uid{$name});
6330                 substr($header, 30, 6) = $gid{$name} if defined($gid{$name});
6331                 substr($header, 18, 6) = $mode{$name} if defined($mode{$name});
6332                 print ($header, $name) if $ok{$name};
6333                 # copy-through the file data
6334                 while ($filesize > 0) {
6335                         my $seg = 8192;
6336                         $seg = $filesize if $filesize < $seg;
6337                         undef $data;
6338                         read STDIN, $data, $seg;
6339                         print $data if $ok{$name};
6340                         $filesize -= $seg;
6341                 }
6342         }
6343         exit(0);
6344         __DATA__
6345 .
6346     # Append to the script the %files data
6347     cat "$@" </dev/null >> $script
6348     /usr/bin/perl $script || pp_error "pp_macos_rewrite_cpio error";
6349 }
6350
6351 pp_macos_files_bom () {
6352     typeset _l t m o g f p st owner
6353     while read t m o g f p st; do
6354         # make sure that $m is padded up to 4 digits long
6355         case "$m" in
6356             ?) m="000$m";;
6357             ??) m="00$m";;
6358             ???) m="0$m";;
6359             ?????*) pp_fatal "pp_macos_writebom: mode '$m' too long";;
6360         esac
6361
6362         # convert owner,group into owner/group in octal
6363         case $o in -)   o=0;; esac
6364         case $g in -)   g=0;; esac
6365         owner=`pp_d2o $o`/`pp_d2o $g`
6366
6367         case $t in
6368             f)
6369                 echo ".$p       10$m    $owner  `
6370                     /usr/bin/cksum < "${pp_destdir}$p" |
6371                     awk '{print $2 "    " $1}'`";;
6372             d)
6373                 echo ".${p%/}   4$m     $owner";;
6374             s)
6375                 rl=`/usr/bin/readlink "${pp_destdir}$p"`
6376                 #test x"$rl" = x"$st" ||
6377                 #    pp_error "symlink mismatch $rl != $st"
6378                 echo ".$p       12$m    $owner  `
6379                     /usr/bin/readlink -n "${pp_destdir}$p" |
6380                     /usr/bin/cksum |
6381                     awk '{print $2 "    " $1}'` $st";;
6382         esac
6383     done
6384 }
6385
6386 pp_macos_bom_fix_parents () {
6387     perl -pe '
6388         sub dirname { my $d=shift; $d=~s,/[^/]*$,,; $d; }
6389         sub chk { my $d=shift;
6390                   &chk(&dirname($d)) if $d =~ m,/,;
6391                   unless ($seen{$d}++) {
6392                       print "$d\t40755\t0/0\n";
6393                   }
6394                 }
6395         m/^\S+/;
6396         &chk(&dirname($&));'
6397 }
6398
6399 pp_macos_files_size () {
6400     typeset _l t m o g f p st owner
6401     while read t m o g f p st; do
6402         case $t in
6403             f)  wc -c < "${pp_destdir}$p";;
6404             s)  echo 4095;;
6405             d)  ;; # always seems to be zero
6406         esac
6407     done | awk '{n+=1+int($1/4096)} END {print n*4}'
6408 }
6409
6410 pp_o2d () {
6411     awk 'BEGIN { x=0; '`echo "$1" |
6412         sed -e 's/./x=x*8+&;/g'`'print x;}' </dev/null
6413 }
6414 pp_d2o () {
6415     case "$1" in
6416         [0-7]) echo $1;;
6417         *) awk 'BEGIN { printf("%o\n", 0+('"$1"'));}' < /dev/null;;
6418     esac
6419 }
6420
6421 pp_macos_mkbom () {
6422     #/usr/bin/mkbom -i $1 $2
6423     typeset path mode ugid size cksum linkpath
6424     typeset bomstage
6425
6426     # Use mkbom if it understands -i (avoids a copy)
6427     if /usr/bin/mkbom -i /dev/null "$2" 2>/dev/null; then
6428         rm -f "$2"
6429         /usr/bin/mkbom -i "$1" "$2"
6430         return
6431     fi
6432
6433     # On 10.4 we have this nonsense.
6434     pp_warn "mkbom workaround: copying source files to staging area"
6435
6436     bomstage=$pp_wrkdir/bom_stage
6437     while IFS=' ' read path mode ugid size cksumi linkpath; do
6438         if test -h "$pp_destdir/$path"; then
6439             /bin/ln -s "$linkpath" "$bomstage/$path"
6440         else
6441             if test -d "$pp_destdir/$path"; then
6442                 /bin/mkdir -p "$bomstage/$path"
6443             else
6444                 /bin/cp "$pp_destdir/$path" "$bomstage/$path"
6445             fi
6446             /bin/chmod $mode "$bomstage/$path"
6447             /usr/sbin/chown `echo $ugid| tr / :` "$bomstage/$path"
6448         fi
6449     done <"$1"
6450     (cd $bomstage && mkbom . $pp_wrkdir/bom_stage.bom) ||
6451         pp_error "mkbom failed"
6452     mv $pp_wrkdir/bom_stage.bom "$2"
6453 }
6454
6455 pp_backend_macos () {
6456     typeset pkgdir Contents Resources lprojdir
6457     typeset Info_plist Description_plist
6458     typeset bundle_vendor bundle_version size
6459
6460     mac_version=`sw_vers -productVersion`
6461     bundle_vendor=${pp_macos_bundle_vendor:-$vendor}
6462
6463     if test -z "$pp_macos_bundle_version"; then
6464         bundle_version=`echo "$version.0.0.0" | sed -n -e 's/[^0-9.]//g' \
6465             -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/p'`
6466         #if test x"$bundle_version" != x"$version"; then
6467         #    pp_warn "converted version from '$version' to '$bundle_version'"
6468         #fi
6469     else
6470         bundle_version="$pp_macos_bundle_version"
6471     fi
6472     source_version=`echo $version | sed 's/.*\.//'`
6473
6474     # build the package layout
6475     pkgdir=$pp_wrkdir/$name.pkg
6476     Contents=$pkgdir/Contents
6477     Resources=$Contents/Resources
6478     lprojdir=$Resources/en.lproj
6479     mkdir $pkgdir $Contents $Resources $lprojdir ||
6480         pp_fatal "Can't make package temporary directories"
6481
6482     echo "major: 1" > $Resources/package_version
6483     echo "minor: 0" >> $Resources/package_version
6484     echo "pmkrpkg1" > $Contents/PkgInfo
6485     case $mac_version in
6486         "10.6"*)
6487             xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/package_version"
6488             xattr -w "com.apple.TextEncoding" "macintosh;0" "$Resources/PkgInfo"
6489             ;;
6490     esac
6491
6492     # compute the installed size
6493     size=`cat $pp_wrkdir/%files.* | pp_macos_files_size`
6494
6495     #-- Create Info.plist
6496     Info_plist=$Contents/Info.plist
6497     pp_macos_plist \
6498         start-plist \{ \
6499         key CFBundleGetInfoString string \
6500             "${pp_macos_bundle_info_string:-$version $bundle_vendor}" \
6501         key CFBundleIdentifier string \
6502             "${pp_macos_bundle_id:-$pp_macos_default_bundle_id_prefix$name}" \
6503     key CFBundleName string "$name" \
6504         key CFBundleShortVersionString string "$bundle_version" \
6505         key IFMajorVersion integer 1 \
6506         key IFMinorVersion integer 0 \
6507         key IFPkgFlagAllowBackRev false \
6508         key IFPkgFlagAuthorizationAction string "RootAuthorization" \
6509         key IFPkgFlagDefaultLocation string "/" \
6510         key IFPkgFlagFollowLinks true \
6511         key IFPkgFlagInstallFat true \
6512         key IFPkgFlagInstalledSize integer $size \
6513         key IFPkgFlagIsRequired false \
6514         key IFPkgFlagOverwritePermissions true \
6515         key IFPkgFlagRelocatable false \
6516         key IFPkgFlagRestartAction string "NoRestart" \
6517         key IFPkgFlagRootVolumeOnly true \
6518         key IFPkgFlagUpdateInstalledLanguages false \
6519         key IFPkgFlagUseUserMask false \
6520         key IFPkgFormatVersion real 0.10000000149011612 \
6521         key SourceVersion string $source_version \
6522         \} end-plist> $Info_plist
6523
6524     # write en.lproj/Description.plist
6525     Description_plist=$lprojdir/Description.plist
6526     pp_macos_plist \
6527         start-plist \{ \
6528         key IFPkgDescriptionDeleteWarning string "" \
6529             key IFPkgDescriptionDescription string "$pp_macos_bundle_info_string" \
6530             key IFPkgDescriptionTitle       string "$name" \
6531             key IFPkgDescriptionVersion string "$version" \
6532         \} end-plist > $Description_plist
6533
6534         # write Resources/files
6535     cat $pp_wrkdir/%files.* | awk '{print $6}' > $Resources/files
6536
6537     # write package size file
6538     printf \
6539 "NumFiles 0
6540 InstalledSize $size
6541 CompressedSize 0
6542 " > $Resources/$name.sizes
6543
6544     # write Resources/postinstall
6545     for cmp in $pp_components; do
6546         if test -s $pp_wrkdir/%pre.$cmp; then
6547             if test ! -s $Resources/preinstall; then
6548                 echo "#!/bin/sh" > $Resources/preinstall
6549                 chmod +x $Resources/preinstall
6550             fi
6551             cat $pp_wrkdir/%pre.$cmp >> $Resources/preinstall
6552             echo : >> $Resources/preinstall
6553         fi
6554     done
6555
6556     # write Resources/postinstall
6557     for cmp in $pp_components; do
6558         if test -s $pp_wrkdir/%post.$cmp; then
6559             if test ! -s $Resources/postinstall; then
6560                 echo "#!/bin/sh" > $Resources/postinstall
6561                 chmod +x $Resources/postinstall
6562             fi
6563             cat $pp_wrkdir/%post.$cmp >> $Resources/postinstall
6564             echo : >> $Resources/postinstall
6565         fi
6566     done
6567
6568     # write Resources/postupgrade)
6569     for cmp in $pp_components; do
6570         if test -s $pp_wrkdir/%postup.$cmp; then
6571             if test ! -s $Resources/postupgrade; then
6572                 echo "#!/bin/sh" > $Resources/postupgrade
6573                 chmod +x $Resources/postupgrade
6574             fi
6575             cat $pp_wrkdir/%postup.$cmp >> $Resources/postupgrade
6576             echo : >> $Resources/postupgrade
6577         fi
6578     done
6579
6580     # write Resources/preremove)
6581     for cmp in $pp_components; do
6582         if test -s $pp_wrkdir/%preun.$cmp; then
6583             if test ! -s $Resources/preremove; then
6584                 echo "#!/bin/sh" > $Resources/preremove
6585                 chmod +x $Resources/preremove
6586             fi
6587             cat $pp_wrkdir/%preun.$cmp >> $Resources/preremove
6588             echo : >> $Resources/preremove
6589         fi
6590     done
6591
6592     # write Resources/postremove)
6593     for cmp in $pp_components; do
6594         if test -s $pp_wrkdir/%postun.$cmp; then
6595             if test ! -s $Resources/postremove; then
6596                 echo "#!/bin/sh" > $Resources/postremove
6597                 chmod +x $Resources/postremove
6598             fi
6599             cat $pp_wrkdir/%postun.$cmp >> $Resources/postremove
6600             echo : >> $Resources/postremove
6601         fi
6602     done
6603
6604     # write uninstall info
6605     echo "version=$version" > $Resources/uninstall
6606     if [ -n "$pp_macos_requires" ];then
6607         echo "requires=$pp_macos_requires" >> $Resources/uninstall
6608     fi
6609
6610     # Create the bill-of-materials (Archive.bom)
6611     cat $pp_wrkdir/%files.* | pp_macos_files_bom | sort |
6612         pp_macos_bom_fix_parents > $pp_wrkdir/tmp.bomls
6613
6614     pp_macos_mkbom $pp_wrkdir/tmp.bomls $Contents/Archive.bom
6615
6616     # Create the cpio archive (Archive.pax.gz)
6617     # On 10.5, we used "-f -" to write explicitly to stdout
6618     (
6619     cd $pp_destdir &&
6620     cat $pp_wrkdir/%files.* | awk '{ print "." $6 }' | sed '/\/$/d' | sort | /bin/pax -w -f - | gzip -9 -c > $Contents/Archive.pax.gz
6621     )
6622
6623         rm -rf $pp_wrkdir/bom_stage
6624 }
6625
6626 pp_backend_macos_cleanup () {
6627     :
6628 }
6629
6630 pp_backend_macos_names () {
6631     echo ${name}.pkg
6632 }
6633
6634 pp_backend_macos_install_script () {
6635     echo '#!/bin/sh'
6636     typeset pkgname platform
6637
6638     pkgname="`pp_backend_macos_names`"
6639     platform="`pp_backend_macos_probe`"
6640     pp_install_script_common
6641
6642     cat <<.
6643         test \$# -eq 0 && usage
6644         op="\$1"; shift
6645
6646         case "\$op" in
6647         list-components)
6648             test \$# -eq 0 || usage \$op
6649             echo "$pp_components"
6650             ;;
6651         list-services)
6652             test \$# -eq 0 || usage \$op
6653             echo "$pp_services"
6654             ;;
6655         list-files)
6656             test \$# -ge 1 || usage \$op
6657             echo \${PP_PKGDESTDIR:-.}/"$pkgname"
6658             ;;
6659         install)
6660             test \$# -ge 1 || usage \$op
6661             vol=/Volumes/pp\$\$
6662             pkg=\$vol/${name}-${version}.pkg
6663             hdiutil attach -readonly -mountpoint \$vol \
6664                 \${PP_PKGDESTDIR:-.}/"$pkgname"
6665             trap "hdiutil detach \$vol" 0
6666             installer -pkginfo -pkg \$pkg
6667             installer -verbose -pkg \$pkg -target /
6668             ;;
6669         uninstall)
6670             test \$# -ge 1 || usage \$op
6671             # XXX
6672             echo "Uninstall not implemented" >&2
6673             exit 1;;
6674         start|stop)
6675             test \$# -ge 1 || usage \$op
6676             ec=0
6677             for svc
6678             do
6679                 # XXX
6680                 echo "\${op} not implemented" >&2
6681                 ec=1
6682             done
6683             exit \$ec
6684             ;;
6685         print-platform)
6686             echo "$platform"
6687             ;;
6688         *)
6689             usage;;
6690         esac
6691 .
6692 }
6693
6694 pp_backend_macos_init_svc_vars () {
6695     :
6696 }
6697
6698 pp_backend_macos_probe () {
6699     typeset name vers arch
6700     case `sw_vers -productName` in
6701          "Mac OS X") name="macos";;
6702          *)          name="unknown";;
6703     esac
6704     vers=`sw_vers -productVersion | sed -e 's/^\([^.]*\)\.\([^.]*\).*/\1\2/'`
6705     arch=`arch`
6706     echo "$name$vers-$arch"
6707 }
6708
6709 pp_backend_macos_vas_platforms () {
6710     echo "osx"    # XXX non-really sure what they do.. it should be "macos"
6711 }
6712 pp_backend_macos_function () {
6713     case $1 in
6714         _pp_macos_search_unused) cat<<'.';;
6715             # Find an unused value in the given path
6716             # args: path attribute minid [maxid]
6717                 pp_tmp_val=$3
6718                 while :; do
6719                     test $pp_tmp_val -ge ${4:-999999} && return 1
6720                     /usr/bin/dscl . -search "$1" "$2" $pp_tmp_val |
6721                         grep . > /dev/null || break
6722                     pp_tmp_val=`expr $pp_tmp_val + 1`
6723                 done
6724                 echo $pp_tmp_val
6725 .
6726         pp_mkgroup:depends) echo _pp_macos_search_unused;;
6727         pp_mkgroup) cat<<'.';;
6728             set -e
6729             /usr/bin/dscl . -read /Groups/"$1" >/dev/null 2>&1 && return
6730             pp_tmp_gid=`_pp_macos_search_unused /Groups PrimaryGroupID 100`
6731             /usr/bin/dscl . -create /Groups/"$1"
6732             /usr/bin/dscl . -create /Groups/"$1" PrimaryGroupID $pp_tmp_gid
6733             /usr/bin/dscl . -create /Groups/"$1" RealName "Group $1"
6734             /usr/bin/dscl . -create /Groups/"$1" GroupMembership ""
6735             /usr/bin/dscl . -create /Groups/"$1" Password '*'
6736 .
6737         pp_mkuser:depends) echo pp_mkgroup _pp_macos_search_unused;;
6738         pp_mkuser) cat<<'.';;
6739             set -e
6740             /usr/bin/dscl . -read /Users/"$1" >/dev/null 2>&1 && return
6741             pp_tmp_uid=`_pp_macos_search_unused /Users UniqueID 100`
6742             pp_mkgroup "${2:-$1}"
6743             pp_tmp_gid=`/usr/bin/dscl . -read /Groups/"${2:-$1}" \
6744                 PrimaryGroupID | awk '{print $2}'`
6745             /usr/bin/dscl . -create /Users/"$1"
6746             /usr/bin/dscl . -create /Users/"$1" PrimaryGroupID $pp_tmp_gid
6747             /usr/bin/dscl . -create /Users/"$1" NFSHomeDirectory \
6748                                     "${3:-/var/empty}"
6749             /usr/bin/dscl . -create /Users/"$1" UserShell \
6750                                     "${4:-/usr/bin/false}"
6751             /usr/bin/dscl . -create /Users/"$1" RealName "$1"
6752             /usr/bin/dscl . -create /Users/"$1" UniqueID $pp_tmp_uid
6753             /usr/bin/dscl . -create /Users/"$1" Password '*'
6754 .
6755         pp_havelib) cat<<'.';;
6756             # (use otool -L to find dependent libraries)
6757             for pp_tmp_dir in `echo "${3:+$3:}/usr/local/lib:/lib:/usr/lib" |
6758                     tr : ' '`; do
6759                 test -r "$pp_tmp_dir/lib$1{$2:+.$2}.dylib" && return 0
6760             done
6761             return 1
6762 .
6763         *) false;;
6764     esac
6765 }
6766
6767 pp_platforms="$pp_platforms inst"
6768
6769 pp_backend_inst_detect () {
6770     case "$1" in
6771         IRIX*)  return 0;;
6772         *)      return 1;;
6773     esac
6774 }
6775
6776 pp_backend_inst_init () {
6777     pp_readlink_fn=pp_ls_readlink
6778 }
6779
6780 pp_backend_inst_create_idb()
6781 {
6782     typeset t m o g f p st
6783
6784     while read t m o g f p st; do
6785         if test x"$o" = x"-"; then
6786             o="root"
6787         fi
6788         if test x"$g" = x"-"; then
6789             g="sys"
6790         fi
6791         case "$t" in
6792             f)  test x"$m" = x"-" && m=444
6793                 echo "f 0$m $o $g $p $p $name.sw.base"
6794                 ;;
6795             d)  test x"$m" = x"-" && m=555
6796                 echo "d 0$m $o $g $p $p $name.sw.base"
6797                 ;;
6798             s)  test x"$m" = x"-" && m=777
6799                 test x"$m" = x"777" ||
6800                     pp_warn "$p: invalid mode $m for symlink, should be 777 or -"
6801                 echo "l 0$m $o $g $p $p $name.sw.base symval($st)"
6802                 ;;
6803         esac
6804     done
6805 }
6806
6807 pp_backend_inst_create_spec()
6808 {
6809     echo "product $name"
6810     echo "    id \"${summary}. Version: ${version}\""
6811     echo "    image sw"
6812     echo "        id \"Software\""
6813     echo "        version $version"
6814     echo "        order 9999"
6815     echo "        subsys base"
6816     echo "            id \"Base Software\""
6817     echo "            replaces self"
6818     echo "            exp $name.sw.base"
6819     echo "        endsubsys"
6820     echo "    endimage"
6821     echo "endproduct"
6822 }
6823
6824 pp_backend_inst () {
6825     curdir=`pwd`
6826
6827     cd "$pp_opt_wrkdir"
6828
6829     # initialize
6830     pp_inst_tardist=tardist
6831     pp_inst_spec=${name}.spec
6832     pp_inst_idb=${name}.idb
6833  
6834     rm -rf $pp_inst_tardist $pp_inst_spec $pp_inst_idb
6835     mkdir -p $pp_inst_tardist
6836
6837     # Create idb file
6838     (for _cmp in $pp_components; do
6839         cat  %files.$_cmp | sort +4u -6 | pp_backend_inst_create_idb
6840     done) >> $pp_inst_idb
6841
6842     pp_backend_inst_create_spec >> $pp_inst_spec
6843
6844     # Generate tardist
6845     gendist -verbose -all -root / -source $pp_opt_destdir -idb $pp_inst_idb -spec $pp_inst_spec -dist $pp_inst_tardist $name
6846     tar -cvf `pp_backend_inst_names` $pp_inst_tardist
6847
6848     cd "$curdir"
6849 }
6850
6851 pp_backend_inst_cleanup () {
6852     :
6853 }
6854
6855 pp_backend_inst_names () {
6856     echo ${name}-${version}.tardist
6857 }
6858
6859 pp_backend_inst_install_script () {
6860     :
6861 }
6862
6863 pp_backend_inst_function () {
6864     echo false
6865 }
6866
6867 pp_backend_inst_init_svc_vars () {
6868     :
6869 }
6870
6871 pp_backend_inst_probe () {
6872     cpu=`hinv|sed -n '/^CPU/{s/000 /k /;s/^CPU: //;s/ Process.*//;s/^MIPS //;p;q;}'|tr A-Z a-z`
6873     echo irix`uname -r`-$cpu
6874 }
6875
6876 pp_backend_inst_vas_platforms () {
6877     echo "irix-65"
6878 }
6879
6880 pp_platforms="$pp_platforms null"
6881
6882 pp_backend_null_detect () {
6883     ! :
6884 }
6885
6886 pp_backend_null_init () {
6887     :
6888 }
6889
6890
6891 pp_backend_null () {
6892     :
6893 }
6894
6895 pp_backend_null_cleanup () {
6896     :
6897 }
6898
6899 pp_backend_null_names () {
6900     :
6901 }
6902
6903 pp_backend_null_install_script () {
6904     :
6905 }
6906
6907 pp_backend_null_function () {
6908     echo false
6909 }
6910
6911 pp_backend_null_init_svc_vars () {
6912     :
6913 }
6914
6915 pp_backend_null_probe () {
6916     echo unknown-unknown
6917 }
6918
6919 pp_backend_null_vas_platforms () {
6920 :
6921 }
6922
6923
6924 quest_require_vas () {
6925     typeset v d
6926
6927     if test $# -ne 1; then
6928         return
6929     fi
6930     set -- `echo "$1" | tr . ' '` 0 0 0
6931
6932     for d
6933     do
6934         echo $d | grep '^[0-9][0-9]*$' > /dev/null ||
6935             pp_error "quest_require_vas: Bad version component $d"
6936     done
6937
6938     test $# -lt 4 &&
6939             pp_error "quest_require_vas: missing version number"
6940
6941     case "$1.$2.$3.$4" in
6942         *.0.0.0) v=$1;;
6943         *.*.0.0) v=$1.$2;;
6944         *.*.*.0) v=$1.$2.$3;;
6945         *)       v=$1.$2.$3.$4;;
6946     esac
6947
6948     cat <<.
6949         if test -x /opt/quest/bin/vastool &&
6950            /opt/quest/bin/vastool -v |
6951             awk 'NR == 1 {print \$4}' |
6952             awk -F. '{ if (\$1<$1 || \$1==$1 && ( \
6953                            \$2<$2 || \$2==$2 && ( \
6954                            \$3<$3 || \$2==$3 && ( \
6955                            \$4<$4 )))) exit(1); }'
6956         then
6957             exit 0
6958         else
6959             echo "Requires VAS $v or later"
6960             exit 1
6961         fi
6962 .
6963 }
6964 pp_main ${1+"$@"}