Mon, 28 Jan 2013 17:37:18 +0100
Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.
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 ###################################################################