Thu, 04 Oct 2012 20:30:05 +0200
Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.
1 ##
2 ## OpenPKG Software Stack Generation
3 ## Copyright (c) 2010-2012 OpenPKG GmbH <http://openpkg.com/>
4 ##
5 ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
6 ## All rights reserved. Licenses which grant limited permission to use,
7 ## copy, modify and distribute this software are available from the
8 ## OpenPKG GmbH.
9 ##
10 ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
11 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
13 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
14 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
15 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
16 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
19 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
20 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
21 ## SUCH DAMAGE.
22 ##
24 # configuration
25 openpkg="${OPENPKG_PREFIX}/bin/openpkg"
26 curl="${OPENPKG_PREFIX}/bin/openpkg curl"
27 shtool="${OPENPKG_PREFIX}/lib/openpkg/shtool"
29 ##
30 ## COMMAND LINE PARSING
31 ##
33 str_usage="[-h|--help] [-v|--verbose <level>] [-o|--output <dir>] [-D|--define <name>=<value> ...] [-u|--unversioned] [-q|--query] <name>.stk"
34 arg_spec="1="
35 opt_spec="h.v:o:D+u.q."
36 opt_alias="h:help,v:verbose,o:output,D:define,u:unversioned,q:query"
37 opt_h=no
38 opt_v=4
39 opt_o="."
40 opt_D=""
41 opt_u=no
42 opt_q=no
44 # parse argument specification string
45 eval `echo $arg_spec |\
46 sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
48 # parse option specification string
49 eval `echo $opt_spec |\
50 sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
52 # parse option alias string
53 eval `echo $opt_alias |\
54 sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
56 # interate over argument line
57 opt_PREV=''
58 while [ $# -gt 0 ]; do
59 # special option stops processing
60 if [ ".$1" = ".--" ]; then
61 shift
62 break
63 fi
65 # determine option and argument
66 opt_ARG_OK=no
67 if [ ".$opt_PREV" != . ]; then
68 # merge previous seen option with argument
69 opt_OPT="$opt_PREV"
70 opt_ARG="$1"
71 opt_ARG_OK=yes
72 opt_PREV=''
73 else
74 # split argument into option and argument
75 case "$1" in
76 --[a-zA-Z0-9]*=*)
77 eval `echo "x$1" |\
78 sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
79 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
80 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
81 ;;
82 --[a-zA-Z0-9]*)
83 opt_OPT=`echo "x$1" | cut -c4-`
84 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
85 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
86 opt_ARG=''
87 ;;
88 -[a-zA-Z0-9]*)
89 eval `echo "x$1" |\
90 sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
91 -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
92 ;;
93 -[a-zA-Z0-9])
94 opt_OPT=`echo "x$1" | cut -c3-`
95 opt_ARG=''
96 ;;
97 *)
98 break
99 ;;
100 esac
101 fi
103 # eat up option
104 shift
106 # determine whether option needs an argument
107 eval "opt_MODE=\$opt_MODE_${opt_OPT}"
108 if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
109 if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
110 opt_PREV="$opt_OPT"
111 continue
112 fi
113 fi
115 # process option
116 case $opt_MODE in
117 '.' )
118 # boolean option
119 eval "opt_${opt_OPT}=yes"
120 ;;
121 ':' )
122 # option with argument (multiple occurances override)
123 eval "opt_${opt_OPT}=\"\$opt_ARG\""
124 ;;
125 '+' )
126 # option with argument (multiple occurances append)
127 eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
128 ;;
129 * )
130 echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2
131 exit 1
132 ;;
133 esac
134 done
135 if [ ".$opt_PREV" != . ]; then
136 echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2
137 exit 1
138 fi
140 # process help option
141 if [ ".$opt_h" = .yes ]; then
142 echo "Usage: $0 $str_usage"
143 exit 0
144 fi
146 # complain about incorrect number of arguments
147 case $arg_MODE in
148 '=' )
149 if [ $# -ne $arg_NUMS ]; then
150 echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
151 exit 1
152 fi
153 ;;
154 '+' )
155 if [ $# -lt $arg_NUMS ]; then
156 echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
157 exit 1
158 fi
159 ;;
160 esac
162 ##
163 ## HELPER FUNCTIONS
164 ##
166 # helper function for graceful termination
167 die () {
168 echo "$0: ERROR: $*"
169 exit 1
170 }
172 # helper function for verbose messages
173 verbose () {
174 lvl="$1"
175 msg="$2"
176 if [ $opt_v -ge $lvl ]; then
177 case "$lvl" in
178 1 ) str_prefix="**" ;;
179 2 ) str_prefix="++" ;;
180 3 ) str_prefix="--" ;;
181 4 ) str_prefix=".." ;;
182 esac
183 echo "${str_prefix} ${msg}"
184 fi
185 }
187 # expand macros
188 macro_expand () {
189 stk="$1"
191 # load all options and their default values
192 options=""
193 for option in `sed <$stk \
194 -e "1,/^%options/d" -e '/^%/,$d' \
195 -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' \
196 -e 's; *[^ ]*$;;'`; do
197 options="$options $option"
198 done
199 eval `sed <$stk \
200 -e "1,/^%options/d" -e '/^%/,$d' \
201 -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \
202 -e 's:^\([^ ]*\) *\([^ ]*\)$:option_\1="\2";:'`
204 # override options with defined values
205 for define in $opt_D; do
206 name=`echo "$define" | sed -e 's;=.*$;;'`
207 value=`echo "$define" | sed -e 's;^.*=;;'`
208 eval "exists=\"\${option_${name}}\""
209 if [ ".$exists" = . ]; then
210 die "definition of not-existing option \"$name\""
211 fi
212 eval "option_${name}=\"${value}\""
213 done
215 # expand macros
216 cmd="sed"
217 for name in $options; do
218 eval "value=\"\${option_${name}}\""
219 cmd="$cmd -e 's;%{[?]$name:\\([^}]*\\)};\1;g'"
220 cmd="$cmd -e 's;%{![?]$name:\\([^}]*\\)};;g'"
221 cmd="$cmd -e 's;%{$name};$value;g'"
222 done
223 cmd="$cmd -e 's;%{[?][^:}]*:[^}]*};;g'"
224 cmd="$cmd -e 's;%{![?][^:}]*:\([^}]*\)};\1;g'"
225 eval "$cmd"
226 }
228 # extract macro-expanded header
229 header () {
230 stk="$1"
231 hdr="$2"
232 exists=`egrep "^${hdr}" $stk`
233 if [ ".$exists" != . ]; then
234 egrep "^${hdr}:" $stk | \
235 sed -e 's;^[^:]*: *;;' -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \
236 macro_expand "$stk"
237 fi
238 }
240 # extract macro-expanded section
241 section () {
242 stk="$1"
243 sec="$2"
244 exists=`egrep "^%${sec}" $stk`
245 if [ ".$exists" != . ]; then
246 sed <$stk \
247 -e "1,/^%${sec}/d" -e '/^%/,$d' \
248 -e 's/#.*$//' -e 's/^ *//' -e 's/ *$//' -e '/^ *$/d' | \
249 macro_expand "$stk"
250 fi
251 }
253 ##
254 ## MAIN
255 ##
257 # determine stack file
258 stk="$1"
259 shift
261 # support stand-alone query operation
262 if [ ".$opt_q" = .yes ]; then
263 name=`header "$stk" "Name"`
264 summary=`header "$stk" "Summary"`
265 packager=`header "$stk" "Packager"`
266 version=`header "$stk" "Version"`
267 release=`header "$stk" "Release"`
268 echo "name=\"$name\";"
269 echo "summary=\"$summary\";"
270 echo "packager=\"$packager\";"
271 echo "version=\"$version\";"
272 echo "release=\"$release\";"
273 sed <$stk \
274 -e "1,/^%options/d" -e '/^%/,$d' \
275 -e 's/#.*$//' -e 's/^ *//' -e '/^ *$/d' \
276 -e 's:^\([^ ]*\) *\([^ ]*\)$:\1="\2";:'
277 exit 0
278 fi
280 # determine temporary directory
281 tmpdir="${TMPDIR-/tmp}"
283 # provide verbose header
284 verbose 1 "OpenPKG Software Stack Generation"
286 # determine information
287 verbose 2 "determining software stack information"
288 name=`header "$stk" "Name"`
289 summary=`header "$stk" "Summary"`
290 packager=`header "$stk" "Packager"`
291 version=`header "$stk" "Version"`
292 release=`header "$stk" "Release"`
293 verbose 3 "Name: $name"
294 verbose 3 "Summary: $summary"
295 verbose 3 "Packager: $packager"
296 verbose 3 "Version: $version"
297 verbose 3 "Release: $release"
298 if [ ".$opt_u" = .yes ]; then
299 basename="$name"
300 else
301 basename="$name-$version-$release"
302 fi
304 # determine URLs
305 verbose 2 "determining software stack packages"
306 repo=`section "$stk" "repository"`
307 verbose 3 "repository: [URL] $repo"
308 $openpkg build -r "$repo" -Z -u -K -B \
309 `section "$stk" "packages"` | \
310 egrep "openpkg curl" | \
311 sed -e 's;^.* \([^ ]*\) || exit.*$;\1;' \
312 -e '/\/openpkg-[0-9].*\.src\.rpm/{h;s/\.src\.rpm$/.src.sh/;p;x}' \
313 >$tmpdir/url.txt
315 # provide header
316 verbose 2 "assembling software stack sources"
318 # download source packages
319 if [ ! -d "$opt_o/$basename.src.d" ]; then
320 verbose 3 "creating: [DIR] $opt_o/$basename.src.d"
321 $shtool mkdir -p -m 755 "$opt_o/$basename.src.d"
322 else
323 verbose 3 "reusing: [DIR] $opt_o/$basename.src.d"
324 fi
325 for url in `cat $tmpdir/url.txt`; do
326 url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'`
327 if [ ! -f "$opt_o/$basename.src.d/$url_file" ]; then
328 verbose 3 "downloading: [FILE] $opt_o/$basename.src.d/$url_file"
329 if [ $opt_v -ge 4 ]; then
330 $curl '-#' -L -k -o $opt_o/$basename.src.d/$url_file $url
331 else
332 $curl -s -L -k -o $opt_o/$basename.src.d/$url_file $url
333 fi
334 else
335 verbose 3 "reusing: [FILE] $opt_o/$basename.src.d/$url_file"
336 fi
337 done
338 for path in $opt_o/$basename.src.d/*.src.sh $opt_o/$basename.src.d/*.src.rpm; do
339 if [ ! -f "$path" ]; then
340 continue
341 fi
342 path_file=`echo $path | sed -e 's;^.*/\([^/]*\)$;\1;'`
343 found=no
344 for url in `cat $tmpdir/url.txt`; do
345 url_file=`echo $url | sed -e 's;^.*/\([^/]*\)$;\1;'`
346 if [ ".$url_file" = ".$path_file" ]; then
347 found=yes
348 break
349 fi
350 done
351 if [ ".$found" = .no ]; then
352 verbose 3 "removing: [FILE] $path"
353 rm -f "$path"
354 fi
355 done
356 rm -f $tmpdir/url.txt
358 # generate XML/RDF index for SRPM packages
359 verbose 3 "generating: [FILE] $opt_o/$basename.src.d/00INDEX.rdf"
360 $openpkg index -r "OpenPKG/SRPM" \
361 -o $opt_o/$basename.src.d/00INDEX.rdf \
362 -i $opt_o/$basename.src.d
364 # generate deployment utility
365 verbose 3 "generating: [FILE] $opt_o/$basename.sh"; \
366 section "$stk" "framework" >$tmpdir/framework.txt
367 section "$stk" "prolog" >$tmpdir/prolog.txt
368 section "$stk" "epilog" >$tmpdir/epilog.txt
369 HAVE_PROLOG=no; if [ ".`cat $tmpdir/prolog.txt`" != . ]; then HAVE_PROLOG=yes; fi
370 HAVE_EPILOG=no; if [ ".`cat $tmpdir/epilog.txt`" != . ]; then HAVE_EPILOG=yes; fi
371 $openpkg build -r "$repo" -Z -u -K \
372 `section "$stk" "packages"` | \
373 grep -v "^#" | \
374 grep -v "^echo" | \
375 grep -v "^rm" | \
376 egrep -v "^(if|fi)" | \
377 grep -v "openpkg curl" | \
378 grep -v "openpkg rpm -Uvh" | \
379 sed -e 's;.*openpkg rpm ;;' \
380 -e 's; || exit.*;;' \
381 -e 's;--rebuild ;;' \
382 -e 's;/.*/\([^/]*\.src\.rpm\);\1;' \
383 -e 's;^\(.*\) \([^/]*\.src\.rpm\);\2 \1;' \
384 -e "s;--define '\\([^ ]*\\) \\([^ ]*\\)';\\1=\\2;g" \
385 -e 's;\.src\.rpm;;' \
386 >$tmpdir/packages.txt
387 sed <$0 \
388 -e '1,/^____/d' \
389 -e "/^CFG_FRAMEWORK=\"/r $tmpdir/framework.txt" \
390 -e "/^CFG_PACKAGES=\"/r $tmpdir/packages.txt" \
391 -e "s;@HAVE_PROLOG@;$HAVE_PROLOG;" \
392 -e "/%prolog/r $tmpdir/prolog.txt" \
393 -e "s;@HAVE_EPILOG@;$HAVE_EPILOG;" \
394 -e "/%epilog/r $tmpdir/epilog.txt" \
395 -e "/^## SHTOOL ##/r $shtool" \
396 -e "s;^\\(CFG_NAME=\"\\).*\\(\"\\);\\1$name\\2;" \
397 -e "s;^\\(CFG_SUMMARY=\"\\).*\\(\"\\);\\1$summary\\2;" \
398 -e "s;^\\(CFG_PACKAGER=\"\\).*\\(\"\\);\\1$packager\\2;" \
399 -e "s;^\\(CFG_VERSION=\"\\).*\\(\"\\);\\1$version\\2;" \
400 -e "s;^\\(CFG_RELEASE=\"\\).*\\(\"\\);\\1$release\\2;" \
401 -e "s;^\\(CFG_UNVERSIONED=\"\\).*\\(\"\\);\\1$opt_u\\2;" \
402 >$opt_o/$basename.sh
404 # cleanup
405 rm -f $tmpdir/framework.txt
406 rm -f $tmpdir/packages.txt
407 rm -f $tmpdir/prolog.txt
408 rm -f $tmpdir/epilog.txt
410 # exit gracefully
411 exit 0
413 ##
414 ## DEPLOYMENT SCRIPT
415 ##
417 ______________________________________________________________________________
418 #!/bin/sh
419 #![OpenPKG]
420 ##
421 ## OpenPKG Software Stack Deployment
422 ## Copyright (c) 2010-2012 OpenPKG GmbH <http://openpkg.com/>
423 ##
424 ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
425 ## All rights reserved. Licenses which grant limited permission to use,
426 ## copy, modify and distribute this software are available from the
427 ## OpenPKG GmbH.
428 ##
429 ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
430 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
431 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
432 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
433 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
434 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
435 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
436 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
437 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
438 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
439 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
440 ## SUCH DAMAGE.
441 ##
443 ##
444 ## COMMAND LINE PARSING
445 ##
447 str_usage="[-h|--help] [-v|--verbose <level>] [-c|--cleanup <level>] [-D|--define <name>=<value> ...] [-s|--srcdir <dir>] [-o|--outdir <dir>] [-t|--tmpdir <dir>] [-S <sudo>]"
448 arg_spec="0="
449 opt_spec="h.v:c:D+s:o:t:S:"
450 opt_alias="h:help,v:verbose,c:cleanup,D:define,s:srcdir,o:outdir,t:tmpdir,S:sudo"
451 opt_h=no
452 opt_v=3
453 opt_c=1
454 opt_D=""
455 opt_s=""
456 opt_o=""
457 opt_t="${TMPDIR-/tmp}"
458 opt_S=""
460 # parse argument specification string
461 eval `echo $arg_spec |\
462 sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
464 # parse option specification string
465 eval `echo $opt_spec |\
466 sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
468 # parse option alias string
469 eval `echo $opt_alias |\
470 sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
472 # interate over argument line
473 opt_PREV=''
474 while [ $# -gt 0 ]; do
475 # special option stops processing
476 if [ ".$1" = ".--" ]; then
477 shift
478 break
479 fi
481 # determine option and argument
482 opt_ARG_OK=no
483 if [ ".$opt_PREV" != . ]; then
484 # merge previous seen option with argument
485 opt_OPT="$opt_PREV"
486 opt_ARG="$1"
487 opt_ARG_OK=yes
488 opt_PREV=''
489 else
490 # split argument into option and argument
491 case "$1" in
492 --[a-zA-Z0-9]*=*)
493 eval `echo "x$1" |\
494 sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
495 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
496 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
497 ;;
498 --[a-zA-Z0-9]*)
499 opt_OPT=`echo "x$1" | cut -c4-`
500 opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
501 eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
502 opt_ARG=''
503 ;;
504 -[a-zA-Z0-9]*)
505 eval `echo "x$1" |\
506 sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
507 -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
508 ;;
509 -[a-zA-Z0-9])
510 opt_OPT=`echo "x$1" | cut -c3-`
511 opt_ARG=''
512 ;;
513 *)
514 break
515 ;;
516 esac
517 fi
519 # eat up option
520 shift
522 # determine whether option needs an argument
523 eval "opt_MODE=\$opt_MODE_${opt_OPT}"
524 if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
525 if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
526 opt_PREV="$opt_OPT"
527 continue
528 fi
529 fi
531 # process option
532 case $opt_MODE in
533 '.' )
534 # boolean option
535 eval "opt_${opt_OPT}=yes"
536 ;;
537 ':' )
538 # option with argument (multiple occurances override)
539 eval "opt_${opt_OPT}=\"\$opt_ARG\""
540 ;;
541 '+' )
542 # option with argument (multiple occurances append)
543 eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
544 ;;
545 * )
546 echo "$0: ERROR: unknown option: \`$opt_OPT'" 1>&2
547 exit 1
548 ;;
549 esac
550 done
551 if [ ".$opt_PREV" != . ]; then
552 echo "$0: ERROR: missing argument to option \`$opt_PREV'" 1>&2
553 exit 1
554 fi
556 # process help option
557 if [ ".$opt_h" = .yes ]; then
558 echo "Usage: $0 $str_usage"
559 exit 0
560 fi
562 # complain about incorrect number of arguments
563 case $arg_MODE in
564 '=' )
565 if [ $# -ne $arg_NUMS ]; then
566 echo "$0: ERROR: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
567 exit 1
568 fi
569 ;;
570 '+' )
571 if [ $# -lt $arg_NUMS ]; then
572 echo "$0: ERROR: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
573 exit 1
574 fi
575 ;;
576 esac
578 # helper function for verbose messages
579 verbose () {
580 lvl="$1"
581 msg="$2"
582 if [ $opt_v -ge $lvl ]; then
583 case "$lvl" in
584 1 ) str_prefix="**" ;;
585 2 ) str_prefix="++" ;;
586 3 ) str_prefix="--" ;;
587 4 ) str_prefix=".." ;;
588 esac
589 echo "${str_prefix} ${msg}"
590 fi
591 }
593 # helper function for graceful termination
594 die () {
595 echo "$0: ERROR: $*"
596 exit 1
597 }
599 ##
600 ## MAIN
601 ##
603 # the stack information
604 CFG_NAME=""
605 CFG_SUMMARY=""
606 CFG_PACKAGER=""
607 CFG_VERSION=""
608 CFG_RELEASE=""
610 # the required OpenPKG framework parameters
611 CFG_FRAMEWORK="
612 "
614 # the required OpenPKG packages
615 # (in topological order and with build options resolved)
616 CFG_PACKAGES="
617 "
619 # whether unversioned output directory should be used
620 CFG_UNVERSIONED=""
622 # display information
623 verbose 1 "OpenPKG Software Stack Deployment"
624 verbose 2 "determining information"
626 # parse OpenPKG framework parameters
627 params="
628 prefix
629 user group
630 susr musr rusr nusr
631 sgrp mgrp rgrp ngrp
632 suid muid ruid nuid
633 sgid mgid rgid ngid
634 tag
635 "
636 for param in $params; do
637 eval "CF_$param=''"
638 done
639 for opt in $CFG_FRAMEWORK; do
640 case "$opt" in
641 --[a-zA-Z0-9-]*=* )
642 name=`echo "$opt" | sed -e 's;^--\([^=]*\)=.*$;\1;'`
643 value=`echo "$opt" | sed -e 's;^--[^=]*=\(.*\)$;\1;'`
644 eval "CF_$name='$value'"
645 ;;
646 esac
647 done
648 for define in $opt_D; do
649 name=`echo "$define" | sed -e 's;=.*$;;'`
650 value=`echo "$define" | sed -e 's;^.*=;;'`
651 eval "CF_$name='$value'"
652 done
653 CFG_FRAMEWORK=''
654 for name in $params; do
655 eval "value=\"\$CF_$name\""
656 if [ ".$value" != . ]; then
657 if [ ".$CFG_FRAMEWORK" = . ]; then
658 CFG_FRAMEWORK="--$name=$value"
659 else
660 CFG_FRAMEWORK="$CFG_FRAMEWORK --$name=$value"
661 fi
662 fi
663 done
664 if [ ".$CF_musr" = . ]; then CF_musr="$CF_user"; fi
665 if [ ".$CF_mgrp" = . ]; then CF_mgrp="$CF_group"; fi
666 if [ ".$CF_rusr" = . ]; then CF_rusr="$CF_user-r"; fi
667 if [ ".$CF_rgrp" = . ]; then CF_rgrp="$CF_group-r"; fi
668 if [ ".$CF_nusr" = . ]; then CF_nusr="$CF_user-n"; fi
669 if [ ".$CF_ngrp" = . ]; then CF_ngrp="$CF_group-n"; fi
670 verbose 3 "name: $CFG_NAME"
671 verbose 3 "summary: $CFG_SUMMARY"
672 verbose 3 "packager: $CFG_PACKAGER"
673 verbose 3 "version: $CFG_VERSION"
674 verbose 3 "release: $CFG_RELEASE"
676 # determine target parameters
677 if [ ".$CF_prefix" = . ]; then
678 die "OpenPKG Framework parameter \"prefix\" required"
679 fi
680 prefix="$CF_prefix"
681 if [ ".$CF_tag" = . ]; then
682 die "OpenPKG Framework parameter \"tag\" required"
683 fi
684 tag="$CF_tag"
685 shtool="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.shtool.sh"
686 sed <$0 -e '1,/^## SHTOOL ##.*/d' >$shtool
687 platform=`sh $shtool platform -n -L -S "" -C "+" -F '%<ap>-%<sp>'`
688 verbose 3 "platform: $platform"
689 verbose 3 "tag: $tag"
690 verbose 3 "prefix: $prefix"
692 # determine operation directories
693 srcdir="$opt_s"
694 if [ ".$srcdir" = . ]; then
695 srcdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.src.d"
696 fi
697 tmpdir="$opt_t/$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.d"
698 if [ ! -d "$tmpdir" ]; then
699 ( umask 077
700 rm -rf "$tmpdir" >/dev/null 2>&1 || true
701 sh $shtool mkdir -p -m 700 "$tmpdir" >/dev/null 2>&1
702 if [ $? -ne 0 ]; then
703 die "failed to create temporary directory: \"$tmpdir\""
704 fi
705 ) || exit $?
706 fi
707 outdir="$opt_o"
708 if [ ".$outdir" = . ]; then
709 if [ ".$CFG_UNVERSIONED" = .yes ]; then
710 outdir="$CFG_NAME.$platform-$tag.d"
711 else
712 outdir="$CFG_NAME-$CFG_VERSION-$CFG_RELEASE.$platform-$tag.d"
713 fi
714 fi
715 if [ ! -d "$outdir" ]; then
716 sh $shtool mkdir -p -m 755 "$outdir" >/dev/null 2>&1
717 if [ $? -ne 0 ]; then
718 die "failed to create output directory: \"$outdir\""
719 fi
720 fi
721 verbose 3 "srcdir: $srcdir"
722 verbose 3 "outdir: $outdir"
723 verbose 3 "tmpdir: $tmpdir"
725 # execute prolog script
726 if [ ".@HAVE_PROLOG@" = .yes ]; then
727 verbose 2 "execute prolog script"
728 cat >$tmpdir/prolog.sh <<EOT
729 #!/bin/sh
730 #![OpenPKG]
731 # %prolog
732 EOT
733 $opt_S sh $tmpdir/prolog.sh
734 rm -f $tmpdir/prolog.sh
735 fi
737 if [ $opt_c -le 1 -a -x "$prefix/bin/openpkg" ]; then
738 # optionally fresh-up OpenPKG instance
739 pkgs=`$prefix/bin/openpkg rpm -qa | egrep -v '^(openpkg-[0-9]|gpg-pubkey-)'`
740 if [ ".$pkgs" != . ]; then
741 verbose 2 "uninstall already installed OpenPKG packages"
742 for pkg in $pkgs; do
743 verbose 3 "REMOVE: $pkg @ $prefix"
744 done
745 $opt_S $prefix/bin/openpkg rpm -e $pkgs || \
746 die "failed to uninstall already installed OpenPKG packages"
747 fi
748 fi
749 if [ $opt_c -le 0 -a -x "$prefix/bin/openpkg" ]; then
750 # optionally destroy OpenPKG instance
751 verbose 2 "destroy existing OpenPKG framework"
752 $opt_S $prefix/bin/openpkg rpm -e openpkg || \
753 die "failed to destroy existing OpenPKG framework"
754 fi
756 # check whether an already existing OpenPKG instance can be reused
757 if [ -x "$prefix/bin/openpkg" ]; then
758 verbose 2 "checking compatibility of existing OpenPKG framework"
759 for name in $params; do
760 case "$name" in
761 user|group ) continue ;;
762 esac
763 eval "value_required=\"\$CF_$name\""
764 if [ ".$value_required" != . ]; then
765 value_existing=`$prefix/bin/openpkg rpm --eval "%{l_${name}}"`
766 if [ ".$value_existing" != ".$value_required" ]; then
767 die "conflict on parameter \"$name\": value required: \"$value_required\", value existing: \"$value_existing\""
768 fi
769 fi
770 done
771 fi
773 # install or upgrade all packages
774 verbose 2 "install or upgrade all OpenPKG packages"
775 DIFS="$IFS"
776 OIFS="$IFS"; IFS="
777 "
778 for spec in $CFG_PACKAGES; do
779 # determine information
780 pkg=`echo "$spec" | sed -e 's;^\([^ ]*\).*$;\1;'`
781 opts=`echo "$spec" | sed -e 's;^[^ ]*;;' -e 's;^ *;;'`
782 name=`echo "$pkg" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*$;\1;'`
783 version=`echo "$pkg" | sed -e 's;^.*-\([^-][^-]*\)-[^-][^-]*$;\1;'`
784 release=`echo "$pkg" | sed -e 's;^.*-[^-][^-]*-\([^-][^-]*\)$;\1;'`
786 if [ ".$name" = .openpkg ]; then
787 #
788 # OpenPKG Framework
789 #
790 if [ ! -f "$outdir/$pkg.$platform-$tag.sh" \
791 -o ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
792 # build (bootstrap & regular)
793 verbose 3 "BOOTSTRAP-BUILD: $srcdir/$pkg.src.sh"
794 verbose 4 "options: $CFG_FRAMEWORK"
795 if [ ! -f "$srcdir/$pkg.src.sh" ]; then
796 die "source shell package not existing: $srcdir/$pkg.src.sh"
797 fi
798 ( TMPDIR="$tmpdir"
799 srcdir="`cd $srcdir && pwd`"
800 cd "$outdir" || exit $?
801 cmd="sh \"$srcdir/$pkg.src.sh\" $CFG_FRAMEWORK"
802 if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
803 eval "$cmd" || \
804 die "failed to build package \"$srcdir/$pkg.src.sh\""
805 rm -f $pkg.src.rpm
806 ) || exit $?
807 fi
808 if [ ! -x "$prefix/bin/openpkg" ]; then
809 # install (bootstrap)
810 if [ ! -f "$outdir/$pkg.$platform-$tag.sh" ]; then
811 die "binary shell package not existing: $outdir/$pkg.$platform-$tag.sh"
812 fi
813 verbose 3 "BOOTSTRAP-INSTALL: $outdir/$pkg.$platform-$tag.sh"
814 cmd="$opt_S sh \"$outdir/$pkg.$platform-$tag.sh\""
815 if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
816 eval "$cmd" || \
817 die "failed to install package \"$outdir/$pkg.$platform-$tag.sh\""
818 else
819 check=`$prefix/bin/openpkg rpm -q openpkg 2>/dev/null`
820 if [ ".$check" != ".$pkg" ]; then
821 # upgrade (regular)
822 if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
823 die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
824 fi
825 verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm"
826 rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
827 $opt_S $prefix/bin/openpkg rpm $rpm_opt \
828 $outdir/$pkg.$platform-$tag.rpm || \
829 die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm"
830 else
831 # keep as-is
832 verbose 3 "KEEP AS-IS: $pkg @ $prefix"
833 fi
834 fi
835 else
836 #
837 # OpenPKG Packages
838 #
839 if [ ! -x "$prefix/bin/openpkg" ]; then
840 # usually will not happen because of correctly
841 # generated topologically correct package list
842 die "command \"$prefix/bin/openpkg\" has to exit for building a regular OpenPKG package" 1>&2
843 fi
844 if [ ! -f $outdir/$pkg.$platform-$tag.rpm ]; then
845 # build (regular)
846 if [ ! -f "$srcdir/$pkg.src.rpm" ]; then
847 die "source RPM package not existing: $srcdir/$pkg.src.rpm"
848 fi
849 verbose 3 "BUILD: $srcdir/$pkg.src.rpm"
850 if [ ".$opts" != . ]; then
851 verbose 4 "options: $opts"
852 fi
853 rm -rf "$tmpdir/$pkg" >/dev/null 2>&1 || true
854 sh $shtool mkdir -p -m 755 "$tmpdir/$pkg" >/dev/null 2>&1
855 cmd="$prefix/bin/openpkg --keep-privileges"
856 cmd="$cmd rpm --rebuild"
857 cmd="$cmd --define \"_specdir $tmpdir/$pkg\""
858 cmd="$cmd --define \"_sourcedir $tmpdir/$pkg\""
859 cmd="$cmd --define \"_builddir $tmpdir/$pkg\""
860 cmd="$cmd --define \"_tmppath $tmpdir/$pkg\""
861 cmd="$cmd --define \"_srcrpmdir $tmpdir/$pkg\""
862 cmd="$cmd --define \"_rpmdir $outdir\""
863 OIFS2="$IFS"; IFS="$DIFS"
864 for opt in $opts; do
865 opt_name=`echo "$opt" | sed -e 's;^\([^=]*\)=.*$;\1;'`
866 opt_value=`echo "$opt" | sed -e 's;^[^=]*=\(.*\)$;\1;'`
867 cmd="$cmd --define \"$opt_name $opt_value\""
868 done
869 IFS="$OIFS2"
870 cmd="$cmd $srcdir/$pkg.src.rpm"
871 if [ $opt_v -lt 4 ]; then cmd="$cmd >/dev/null 2>&1"; fi
872 eval "$cmd" || \
873 die "failed to build package \"$srcdir/$pkg.src.rpm\""
874 fi
875 check=`$prefix/bin/openpkg rpm -q "$name" 2>/dev/null`
876 if [ ".$check" = ".package $name is not installed" ]; then
877 # install (regular)
878 if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
879 die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
880 fi
881 verbose 3 "INSTALL: $outdir/$pkg.$platform-$tag.rpm"
882 rpm_opt="-i"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
883 $opt_S $prefix/bin/openpkg rpm $rpm_opt \
884 $outdir/$pkg.$platform-$tag.rpm || \
885 die "failed to install package: $outdir/$pkg.$platform-$tag.rpm"
886 elif [ ".$check" != ".$pkg" ]; then
887 # upgrade (regular)
888 if [ ! -f "$outdir/$pkg.$platform-$tag.rpm" ]; then
889 die "binary RPM package not existing: $outdir/$pkg.$platform-$tag.rpm"
890 fi
891 verbose 3 "UPGRADE: $outdir/$pkg.$platform-$tag.rpm"
892 rpm_opt="-U"; if [ $opt_v -ge 4 ]; then rpm_opt="${rpm_opt}vh"; fi
893 $opt_S $prefix/bin/openpkg rpm $rpm_opt \
894 $outdir/$pkg.$platform-$tag.rpm || \
895 die "failed to upgrade package: $outdir/$pkg.$platform-$tag.rpm"
896 else
897 # keep as-is
898 verbose 3 "KEEP AS-IS: $pkg @ $prefix"
899 fi
900 fi
901 done
902 IFS="$OIFS"
904 # optionally remove residue packages from binary RPM package directory
905 if [ $opt_c -lt 3 ]; then
906 verbose 2 "cleanup target directory from residue packages"
907 for pkg in $outdir/*.sh $outdir/*.rpm; do
908 if [ ! -f "$pkg" ]; then
909 continue
910 fi
911 pkg_base=`echo "$pkg" | sed -e 's;^.*/\([^/][^/]*-[0-9][^/-]*-[0-9][0-9.]*\)\.[^/][^/]*$;\1;'`
912 erase=yes
913 for spec in $CFG_PACKAGES; do
914 spec_base=`echo "$spec" | sed -e 's;^\(.*-[^-][^-]*-[^-][^-]*\).*$;\1;'`
915 if [ ".$pkg_base" = ".$spec_base" ]; then
916 erase=no
917 break
918 fi
919 done
920 if [ ".$erase" = .yes ]; then
921 verbose 3 "REMOVE: $pkg"
922 rm -f "$pkg"
923 fi
924 done
925 fi
927 # optionally remove residue packages from OpenPKG instance
928 if [ $opt_c -lt 3 ]; then
929 verbose 2 "cleanup OpenPKG instance from residue packages"
930 for pkg1 in `$prefix/bin/openpkg rpm -qa | egrep -v '^(openpkg-[0-9]|gpg-pubkey-)'`; do
931 name1=`echo "$pkg1" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*$;\1;'`
932 erase=yes
933 for spec in $CFG_PACKAGES; do
934 name2=`echo "$spec" | sed -e 's;^\(.*\)-[^-][^-]*-[^-][^-]*.*$;\1;'`
935 if [ ".$name1" = ".$name2" ]; then
936 erase=no
937 break
938 fi
939 done
940 if [ ".$erase" = .yes ]; then
941 verbose 3 "REMOVE: pkg1 @ $prefix"
942 $opt_S $prefix/bin/openpkg rpm -e "$pkg1" || \
943 die "failed to erase residue package \"$pkg1\""
944 fi
945 done
946 fi
948 # execute epilog script
949 if [ ".@HAVE_EPILOG@" = .yes ]; then
950 verbose 2 "execute epilog script"
951 cat >$tmpdir/epilog.sh <<EOT
952 #!/bin/sh
953 #![OpenPKG]
954 # %epilog
955 EOT
956 $opt_S sh $tmpdir/epilog.sh
957 rm -f $tmpdir/epilog.sh
958 fi
960 # cleanup
961 rm -f $shtool >/dev/null 3>&1 || true
962 rm -rf $tmpdir >/dev/null 2>&1 || true
964 exit 0
966 ## SHTOOL ###################################################################