/[gentoo-x86]/eclass/eutils.eclass
Gentoo

Diff of /eclass/eutils.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.353 Revision 1.386
1# Copyright 1999-2009 Gentoo Foundation 1# Copyright 1999-2012 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.353 2011/01/09 02:16:53 vapier Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.386 2012/03/01 22:10:50 naota Exp $
4 4
5# @ECLASS: eutils.eclass 5# @ECLASS: eutils.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# base-system@gentoo.org 7# base-system@gentoo.org
8# @BLURB: many extra (but common) functions that are used in ebuilds 8# @BLURB: many extra (but common) functions that are used in ebuilds
13# home rather than having multiple ebuilds implementing the same thing. 13# home rather than having multiple ebuilds implementing the same thing.
14# 14#
15# Due to the nature of this eclass, some functions may have maintainers 15# Due to the nature of this eclass, some functions may have maintainers
16# different from the overall eclass! 16# different from the overall eclass!
17 17
18inherit multilib portability 18if [[ ${___ECLASS_ONCE_EUTILS} != "recur -_+^+_- spank" ]] ; then
19___ECLASS_ONCE_EUTILS="recur -_+^+_- spank"
20
21inherit multilib user
19 22
20DESCRIPTION="Based on the ${ECLASS} eclass" 23DESCRIPTION="Based on the ${ECLASS} eclass"
21 24
22if has "${EAPI:-0}" 0 1 2; then 25if has "${EAPI:-0}" 0 1 2; then
23 26
64fi 67fi
65 68
66# @FUNCTION: eqawarn 69# @FUNCTION: eqawarn
67# @USAGE: [message] 70# @USAGE: [message]
68# @DESCRIPTION: 71# @DESCRIPTION:
69# Proxy to einfo for package managers that don't provide eqawarn and use the PM 72# Proxy to ewarn for package managers that don't provide eqawarn and use the PM
70# implementation if available. 73# implementation if available. Reuses PORTAGE_ELOG_CLASSES as set by the dev
74# profile.
71if ! declare -F eqawarn >/dev/null ; then 75if ! declare -F eqawarn >/dev/null ; then
72 eqawarn() { 76 eqawarn() {
73 einfo "$@" 77 has qa ${PORTAGE_ELOG_CLASSES} && ewarn "$@"
78 :
74 } 79 }
75fi 80fi
76 81
77# @FUNCTION: ecvs_clean 82# @FUNCTION: ecvs_clean
78# @USAGE: [list of dirs] 83# @USAGE: [list of dirs]
93esvn_clean() { 98esvn_clean() {
94 [[ -z $* ]] && set -- . 99 [[ -z $* ]] && set -- .
95 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf 100 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
96} 101}
97 102
103# @FUNCTION: estack_push
104# @USAGE: <stack> [items to push]
105# @DESCRIPTION:
106# Push any number of items onto the specified stack. Pick a name that
107# is a valid variable (i.e. stick to alphanumerics), and push as many
108# items as you like onto the stack at once.
109#
110# The following code snippet will echo 5, then 4, then 3, then ...
111# @CODE
112# estack_push mystack 1 2 3 4 5
113# while estack_pop mystack i ; do
114# echo "${i}"
115# done
116# @CODE
117estack_push() {
118 [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments"
119 local stack_name="__ESTACK_$1__" ; shift
120 eval ${stack_name}+=\( \"\$@\" \)
121}
122
123# @FUNCTION: estack_pop
124# @USAGE: <stack> [variable]
125# @DESCRIPTION:
126# Pop a single item off the specified stack. If a variable is specified,
127# the popped item is stored there. If no more items are available, return
128# 1, else return 0. See estack_push for more info.
129estack_pop() {
130 [[ $# -eq 0 || $# -gt 2 ]] && die "estack_pop: incorrect # of arguments"
131
132 # We use the fugly __estack_xxx var names to avoid collision with
133 # passing back the return value. If we used "local i" and the
134 # caller ran `estack_pop ... i`, we'd end up setting the local
135 # copy of "i" rather than the caller's copy. The __estack_xxx
136 # garbage is preferable to using $1/$2 everywhere as that is a
137 # bit harder to read.
138 local __estack_name="__ESTACK_$1__" ; shift
139 local __estack_retvar=$1 ; shift
140 eval local __estack_i=\${#${__estack_name}\[@\]}
141 # Don't warn -- let the caller interpret this as a failure
142 # or as normal behavior (akin to `shift`)
143 [[ $(( --__estack_i )) -eq -1 ]] && return 1
144
145 if [[ -n ${__estack_retvar} ]] ; then
146 eval ${__estack_retvar}=\"\${${__estack_name}\[${__estack_i}\]}\"
147 fi
148 eval unset ${__estack_name}\[${__estack_i}\]
149}
150
98# @FUNCTION: eshopts_push 151# @FUNCTION: eshopts_push
99# @USAGE: [options to `set` or `shopt`] 152# @USAGE: [options to `set` or `shopt`]
100# @DESCRIPTION: 153# @DESCRIPTION:
101# Often times code will want to enable a shell option to change code behavior. 154# Often times code will want to enable a shell option to change code behavior.
102# Since changing shell options can easily break other pieces of code (which 155# Since changing shell options can easily break other pieces of code (which
107# rather than `set` as there are some options only available via that. 160# rather than `set` as there are some options only available via that.
108# 161#
109# A common example is to disable shell globbing so that special meaning/care 162# A common example is to disable shell globbing so that special meaning/care
110# may be used with variables/arguments to custom functions. That would be: 163# may be used with variables/arguments to custom functions. That would be:
111# @CODE 164# @CODE
112# eshopts_push -o noglob 165# eshopts_push -s noglob
113# for x in ${foo} ; do 166# for x in ${foo} ; do
114# if ...some check... ; then 167# if ...some check... ; then
115# eshopts_pop 168# eshopts_pop
116# return 0 169# return 0
117# fi 170# fi
118# done 171# done
119# eshopts_pop 172# eshopts_pop
120# @CODE 173# @CODE
121eshopts_push() { 174eshopts_push() {
122 # have to assume __ESHOPTS_SAVE__ isn't screwed with
123 # as a `declare -a` here will reset its value
124 local i=${#__ESHOPTS_SAVE__[@]}
125 if [[ $1 == -[su] ]] ; then 175 if [[ $1 == -[su] ]] ; then
126 __ESHOPTS_SAVE__[$i]=$(shopt -p) 176 estack_push eshopts "$(shopt -p)"
127 [[ $# -eq 0 ]] && return 0 177 [[ $# -eq 0 ]] && return 0
128 shopt "$@" || die "eshopts_push: bad options to shopt: $*" 178 shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*"
129 else 179 else
130 __ESHOPTS_SAVE__[$i]=$- 180 estack_push eshopts $-
131 [[ $# -eq 0 ]] && return 0 181 [[ $# -eq 0 ]] && return 0
132 set "$@" || die "eshopts_push: bad options to set: $*" 182 set "$@" || die "${FUNCNAME}: bad options to set: $*"
133 fi 183 fi
134} 184}
135 185
136# @FUNCTION: eshopts_pop 186# @FUNCTION: eshopts_pop
137# @USAGE: 187# @USAGE:
138# @DESCRIPTION: 188# @DESCRIPTION:
139# Restore the shell options to the state saved with the corresponding 189# Restore the shell options to the state saved with the corresponding
140# eshopts_push call. See that function for more details. 190# eshopts_push call. See that function for more details.
141eshopts_pop() { 191eshopts_pop() {
142 [[ $# -ne 0 ]] && die "eshopts_pop takes no arguments" 192 local s
143 local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 )) 193 estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
144 [[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
145 local s=${__ESHOPTS_SAVE__[$i]}
146 unset __ESHOPTS_SAVE__[$i]
147 if [[ ${s} == "shopt -"* ]] ; then 194 if [[ ${s} == "shopt -"* ]] ; then
148 eval "${s}" || die "eshopts_pop: sanity: invalid shopt options: ${s}" 195 eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}"
149 else 196 else
150 set +$- || die "eshopts_pop: sanity: invalid shell settings: $-" 197 set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-"
151 set -${s} || die "eshopts_pop: sanity: unable to restore saved shell settings: ${s}" 198 set -${s} || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}"
152 fi 199 fi
200}
201
202# @FUNCTION: eumask_push
203# @USAGE: <new umask>
204# @DESCRIPTION:
205# Set the umask to the new value specified while saving the previous
206# value onto a stack. Useful for temporarily changing the umask.
207eumask_push() {
208 estack_push eumask "$(umask)"
209 umask "$@" || die "${FUNCNAME}: bad options to umask: $*"
210}
211
212# @FUNCTION: eumask_pop
213# @USAGE:
214# @DESCRIPTION:
215# Restore the previous umask state.
216eumask_pop() {
217 [[ $# -eq 0 ]] || die "${FUNCNAME}: we take no options"
218 local s
219 estack_pop eumask s || die "${FUNCNAME}: unbalanced push"
220 umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
153} 221}
154 222
155# @VARIABLE: EPATCH_SOURCE 223# @VARIABLE: EPATCH_SOURCE
156# @DESCRIPTION: 224# @DESCRIPTION:
157# Default directory to search for patches. 225# Default directory to search for patches.
250 318
251 elif [[ -d $1 ]] ; then 319 elif [[ -d $1 ]] ; then
252 # Some people like to make dirs of patches w/out suffixes (vim) 320 # Some people like to make dirs of patches w/out suffixes (vim)
253 set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"} 321 set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
254 322
323 elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
324 # Re-use EPATCH_SOURCE as a search dir
325 epatch "${EPATCH_SOURCE}/$1"
326 return $?
327
255 else 328 else
256 # sanity check ... if it isn't a dir or file, wtf man ? 329 # sanity check ... if it isn't a dir or file, wtf man ?
257 [[ $# -ne 0 ]] && EPATCH_SOURCE=$1 330 [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
258 echo 331 echo
259 eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:" 332 eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:"
289 # ???_arch_foo.patch 362 # ???_arch_foo.patch
290 # Else, skip this input altogether 363 # Else, skip this input altogether
291 local a=${patchname#*_} # strip the ???_ 364 local a=${patchname#*_} # strip the ???_
292 a=${a%%_*} # strip the _foo.patch 365 a=${a%%_*} # strip the _foo.patch
293 if ! [[ ${SINGLE_PATCH} == "yes" || \ 366 if ! [[ ${SINGLE_PATCH} == "yes" || \
294 ${EPATCH_FORCE} == "yes" || \ 367 ${EPATCH_FORCE} == "yes" || \
295 ${a} == all || \ 368 ${a} == all || \
296 ${a} == ${ARCH} ]] 369 ${a} == ${ARCH} ]]
297 then 370 then
298 continue 371 continue
299 fi 372 fi
300 373
301 # Let people filter things dynamically 374 # Let people filter things dynamically
329 local STDERR_TARGET="${T}/${patchname}.out" 402 local STDERR_TARGET="${T}/${patchname}.out"
330 if [[ -e ${STDERR_TARGET} ]] ; then 403 if [[ -e ${STDERR_TARGET} ]] ; then
331 STDERR_TARGET="${T}/${patchname}-$$.out" 404 STDERR_TARGET="${T}/${patchname}-$$.out"
332 fi 405 fi
333 406
334 printf "***** %s *****\n\n" "${patchname}" > "${STDERR_TARGET}" 407 printf "***** %s *****\nPWD: %s\n\n" "${patchname}" "${PWD}" > "${STDERR_TARGET}"
335 408
336 # Decompress the patch if need be 409 # Decompress the patch if need be
337 local count=0 410 local count=0
338 local PATCH_TARGET 411 local PATCH_TARGET
339 if [[ -n ${PIPE_CMD} ]] ; then 412 if [[ -n ${PIPE_CMD} ]] ; then
367 eqawarn " In the future this will cause a failure." 440 eqawarn " In the future this will cause a failure."
368 eqawarn "${rel_paths}" 441 eqawarn "${rel_paths}"
369 fi 442 fi
370 443
371 # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/ 444 # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
445 local patch_cmd
372 while [[ ${count} -lt 5 ]] ; do 446 while [[ ${count} -lt 5 ]] ; do
447 patch_cmd="${BASH_ALIASES[patch]:-patch} -p${count} ${EPATCH_OPTS}"
448
373 # Generate some useful debug info ... 449 # Generate some useful debug info ...
374 ( 450 (
375 _epatch_draw_line "***** ${patchname} *****" 451 _epatch_draw_line "***** ${patchname} *****"
376 echo 452 echo
377 echo "PATCH COMMAND: patch -p${count} ${EPATCH_OPTS} < '${PATCH_TARGET}'" 453 echo "PATCH COMMAND: ${patch_cmd} < '${PATCH_TARGET}'"
378 echo 454 echo
379 _epatch_draw_line "***** ${patchname} *****" 455 _epatch_draw_line "***** ${patchname} *****"
456 ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
457 ret=$?
458 echo
459 echo "patch program exited with status ${ret}"
460 exit ${ret}
380 ) >> "${STDERR_TARGET}" 461 ) >> "${STDERR_TARGET}"
381 462
382 if (patch -p${count} ${EPATCH_OPTS} --dry-run -f < "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then 463 if [ $? -eq 0 ] ; then
383 ( 464 (
384 _epatch_draw_line "***** ${patchname} *****" 465 _epatch_draw_line "***** ${patchname} *****"
385 echo 466 echo
386 echo "ACTUALLY APPLYING ${patchname} ..." 467 echo "ACTUALLY APPLYING ${patchname} ..."
387 echo 468 echo
388 _epatch_draw_line "***** ${patchname} *****" 469 _epatch_draw_line "***** ${patchname} *****"
389 patch -p${count} ${EPATCH_OPTS} < "${PATCH_TARGET}" 2>&1 470 ${patch_cmd} < "${PATCH_TARGET}" 2>&1
471 ret=$?
472 echo
473 echo "patch program exited with status ${ret}"
474 exit ${ret}
390 ) >> "${STDERR_TARGET}" 475 ) >> "${STDERR_TARGET}"
391 476
392 if [ $? -ne 0 ] ; then 477 if [ $? -ne 0 ] ; then
393 echo 478 echo
394 eerror "A dry-run of patch command succeeded, but actually" 479 eerror "A dry-run of patch command succeeded, but actually"
417 eerror " ${STDERR_TARGET}" 502 eerror " ${STDERR_TARGET}"
418 echo 503 echo
419 die "Failed Patch: ${patchname}!" 504 die "Failed Patch: ${patchname}!"
420 fi 505 fi
421 506
422 # if everything worked, delete the patch log 507 # if everything worked, delete the full debug patch log
423 rm -f "${STDERR_TARGET}" 508 rm -f "${STDERR_TARGET}"
509
510 # then log away the exact stuff for people to review later
511 cat <<-EOF >> "${T}/epatch.log"
512 PATCH: ${x}
513 CMD: ${patch_cmd}
514 PWD: ${PWD}
515
516 EOF
424 eend 0 517 eend 0
425 done 518 done
426 519
427 [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching" 520 [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
428 : # everything worked 521 : # everything worked
429} 522}
523
524# @FUNCTION: epatch_user
525# @USAGE:
526# @DESCRIPTION:
527# Applies user-provided patches to the source tree. The patches are
528# taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>/, where the first
529# of these three directories to exist will be the one to use, ignoring
530# any more general directories which might exist as well.
531#
532# User patches are intended for quick testing of patches without ebuild
533# modifications, as well as for permanent customizations a user might
534# desire. Obviously, there can be no official support for arbitrarily
535# patched ebuilds. So whenever a build log in a bug report mentions that
536# user patches were applied, the user should be asked to reproduce the
537# problem without these.
538#
539# Not all ebuilds do call this function, so placing patches in the
540# stated directory might or might not work, depending on the package and
541# the eclasses it inherits and uses. It is safe to call the function
542# repeatedly, so it is always possible to add a call at the ebuild
543# level. The first call is the time when the patches will be
544# applied.
545#
546# Ideally, this function should be called after gentoo-specific patches
547# have been applied, so that their code can be modified as well, but
548# before calls to e.g. eautoreconf, as the user patches might affect
549# autotool input files as well.
430epatch_user() { 550epatch_user() {
431 [[ $# -ne 0 ]] && die "epatch_user takes no options" 551 [[ $# -ne 0 ]] && die "epatch_user takes no options"
432 552
553 # Allow multiple calls to this function; ignore all but the first
554 local applied="${T}/epatch_user.log"
555 [[ -e ${applied} ]] && return 2
556
433 # don't clobber any EPATCH vars that the parent might want 557 # don't clobber any EPATCH vars that the parent might want
434 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches 558 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
435 for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do 559 for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}; do
436 EPATCH_SOURCE=${base}/${CTARGET}/${check} 560 EPATCH_SOURCE=${base}/${CTARGET}/${check}
437 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check} 561 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
438 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check} 562 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
439 if [[ -d ${EPATCH_SOURCE} ]] ; then 563 if [[ -d ${EPATCH_SOURCE} ]] ; then
440 EPATCH_SOURCE=${EPATCH_SOURCE} \ 564 EPATCH_SOURCE=${EPATCH_SOURCE} \
441 EPATCH_SUFFIX="patch" \ 565 EPATCH_SUFFIX="patch" \
442 EPATCH_FORCE="yes" \ 566 EPATCH_FORCE="yes" \
443 EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \ 567 EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
444 epatch 568 epatch
569 echo "${EPATCH_SOURCE}" > "${applied}"
445 return 0 570 return 0
446 fi 571 fi
447 done 572 done
573 echo "none" > "${applied}"
448 return 1 574 return 1
449} 575}
450 576
451# @FUNCTION: emktemp 577# @FUNCTION: emktemp
452# @USAGE: [temp dir] 578# @USAGE: [temp dir]
481 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX 607 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
482 fi 608 fi
483 fi 609 fi
484} 610}
485 611
486# @FUNCTION: egetent
487# @USAGE: <database> <key>
488# @MAINTAINER:
489# base-system@gentoo.org (Linux)
490# Joe Jezak <josejx@gmail.com> (OS X)
491# usata@gentoo.org (OS X)
492# Aaron Walker <ka0ttic@gentoo.org> (FreeBSD)
493# @DESCRIPTION:
494# Small wrapper for getent (Linux),
495# nidump (< Mac OS X 10.5), dscl (Mac OS X 10.5),
496# and pw (FreeBSD) used in enewuser()/enewgroup()
497egetent() {
498 case ${CHOST} in
499 *-darwin[678])
500 case "$2" in
501 *[!0-9]*) # Non numeric
502 nidump $1 . | awk -F":" "{ if (\$1 ~ /^$2$/) {print \$0;exit;} }"
503 ;;
504 *) # Numeric
505 nidump $1 . | awk -F":" "{ if (\$3 == $2) {print \$0;exit;} }"
506 ;;
507 esac
508 ;;
509 *-darwin*)
510 local mytype=$1
511 [[ "passwd" == $mytype ]] && mytype="Users"
512 [[ "group" == $mytype ]] && mytype="Groups"
513 case "$2" in
514 *[!0-9]*) # Non numeric
515 dscl . -read /$mytype/$2 2>/dev/null |grep RecordName
516 ;;
517 *) # Numeric
518 local mykey="UniqueID"
519 [[ $mytype == "Groups" ]] && mykey="PrimaryGroupID"
520 dscl . -search /$mytype $mykey $2 2>/dev/null
521 ;;
522 esac
523 ;;
524 *-freebsd*|*-dragonfly*)
525 local opts action="user"
526 [[ $1 == "passwd" ]] || action="group"
527
528 # lookup by uid/gid
529 if [[ $2 == [[:digit:]]* ]] ; then
530 [[ ${action} == "user" ]] && opts="-u" || opts="-g"
531 fi
532
533 pw show ${action} ${opts} "$2" -q
534 ;;
535 *-netbsd*|*-openbsd*)
536 grep "$2:\*:" /etc/$1
537 ;;
538 *)
539 type -p nscd >& /dev/null && nscd -i "$1"
540 getent "$1" "$2"
541 ;;
542 esac
543}
544
545# @FUNCTION: enewuser
546# @USAGE: <user> [uid] [shell] [homedir] [groups] [params]
547# @DESCRIPTION:
548# Same as enewgroup, you are not required to understand how to properly add
549# a user to the system. The only required parameter is the username.
550# Default uid is (pass -1 for this) next available, default shell is
551# /bin/false, default homedir is /dev/null, there are no default groups,
552# and default params sets the comment as 'added by portage for ${PN}'.
553enewuser() {
554 case ${EBUILD_PHASE} in
555 unpack|compile|test|install)
556 eerror "'enewuser()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
557 eerror "Package fails at QA and at life. Please file a bug."
558 die "Bad package! enewuser is only for use in pkg_* functions!"
559 esac
560
561 # get the username
562 local euser=$1; shift
563 if [[ -z ${euser} ]] ; then
564 eerror "No username specified !"
565 die "Cannot call enewuser without a username"
566 fi
567
568 # lets see if the username already exists
569 if [[ -n $(egetent passwd "${euser}") ]] ; then
570 return 0
571 fi
572 einfo "Adding user '${euser}' to your system ..."
573
574 # options to pass to useradd
575 local opts=
576
577 # handle uid
578 local euid=$1; shift
579 if [[ -n ${euid} && ${euid} != -1 ]] ; then
580 if [[ ${euid} -gt 0 ]] ; then
581 if [[ -n $(egetent passwd ${euid}) ]] ; then
582 euid="next"
583 fi
584 else
585 eerror "Userid given but is not greater than 0 !"
586 die "${euid} is not a valid UID"
587 fi
588 else
589 euid="next"
590 fi
591 if [[ ${euid} == "next" ]] ; then
592 for ((euid = 101; euid <= 999; euid++)); do
593 [[ -z $(egetent passwd ${euid}) ]] && break
594 done
595 fi
596 opts="${opts} -u ${euid}"
597 einfo " - Userid: ${euid}"
598
599 # handle shell
600 local eshell=$1; shift
601 if [[ ! -z ${eshell} ]] && [[ ${eshell} != "-1" ]] ; then
602 if [[ ! -e ${ROOT}${eshell} ]] ; then
603 eerror "A shell was specified but it does not exist !"
604 die "${eshell} does not exist in ${ROOT}"
605 fi
606 if [[ ${eshell} == */false || ${eshell} == */nologin ]] ; then
607 eerror "Do not specify ${eshell} yourself, use -1"
608 die "Pass '-1' as the shell parameter"
609 fi
610 else
611 for shell in /sbin/nologin /usr/sbin/nologin /bin/false /usr/bin/false /dev/null ; do
612 [[ -x ${ROOT}${shell} ]] && break
613 done
614
615 if [[ ${shell} == "/dev/null" ]] ; then
616 eerror "Unable to identify the shell to use, proceeding with userland default."
617 case ${USERLAND} in
618 GNU) shell="/bin/false" ;;
619 BSD) shell="/sbin/nologin" ;;
620 Darwin) shell="/usr/sbin/nologin" ;;
621 *) die "Unable to identify the default shell for userland ${USERLAND}"
622 esac
623 fi
624
625 eshell=${shell}
626 fi
627 einfo " - Shell: ${eshell}"
628 opts="${opts} -s ${eshell}"
629
630 # handle homedir
631 local ehome=$1; shift
632 if [[ -z ${ehome} ]] || [[ ${ehome} == "-1" ]] ; then
633 ehome="/dev/null"
634 fi
635 einfo " - Home: ${ehome}"
636 opts="${opts} -d ${ehome}"
637
638 # handle groups
639 local egroups=$1; shift
640 if [[ ! -z ${egroups} ]] ; then
641 local oldifs=${IFS}
642 local defgroup="" exgroups=""
643
644 export IFS=","
645 for g in ${egroups} ; do
646 export IFS=${oldifs}
647 if [[ -z $(egetent group "${g}") ]] ; then
648 eerror "You must add group ${g} to the system first"
649 die "${g} is not a valid GID"
650 fi
651 if [[ -z ${defgroup} ]] ; then
652 defgroup=${g}
653 else
654 exgroups="${exgroups},${g}"
655 fi
656 export IFS=","
657 done
658 export IFS=${oldifs}
659
660 opts="${opts} -g ${defgroup}"
661 if [[ ! -z ${exgroups} ]] ; then
662 opts="${opts} -G ${exgroups:1}"
663 fi
664 else
665 egroups="(none)"
666 fi
667 einfo " - Groups: ${egroups}"
668
669 # handle extra and add the user
670 local oldsandbox=${SANDBOX_ON}
671 export SANDBOX_ON="0"
672 case ${CHOST} in
673 *-darwin*)
674 ### Make the user
675 if [[ -z $@ ]] ; then
676 dscl . create /users/${euser} uid ${euid}
677 dscl . create /users/${euser} shell ${eshell}
678 dscl . create /users/${euser} home ${ehome}
679 dscl . create /users/${euser} realname "added by portage for ${PN}"
680 ### Add the user to the groups specified
681 local oldifs=${IFS}
682 export IFS=","
683 for g in ${egroups} ; do
684 dscl . merge /groups/${g} users ${euser}
685 done
686 export IFS=${oldifs}
687 else
688 einfo "Extra options are not supported on Darwin yet"
689 einfo "Please report the ebuild along with the info below"
690 einfo "eextra: $@"
691 die "Required function missing"
692 fi
693 ;;
694 *-freebsd*|*-dragonfly*)
695 if [[ -z $@ ]] ; then
696 pw useradd ${euser} ${opts} \
697 -c "added by portage for ${PN}" \
698 die "enewuser failed"
699 else
700 einfo " - Extra: $@"
701 pw useradd ${euser} ${opts} \
702 "$@" || die "enewuser failed"
703 fi
704 ;;
705
706 *-netbsd*)
707 if [[ -z $@ ]] ; then
708 useradd ${opts} ${euser} || die "enewuser failed"
709 else
710 einfo " - Extra: $@"
711 useradd ${opts} ${euser} "$@" || die "enewuser failed"
712 fi
713 ;;
714
715 *-openbsd*)
716 if [[ -z $@ ]] ; then
717 useradd -u ${euid} -s ${eshell} \
718 -d ${ehome} -c "Added by portage for ${PN}" \
719 -g ${egroups} ${euser} || die "enewuser failed"
720 else
721 einfo " - Extra: $@"
722 useradd -u ${euid} -s ${eshell} \
723 -d ${ehome} -c "Added by portage for ${PN}" \
724 -g ${egroups} ${euser} "$@" || die "enewuser failed"
725 fi
726 ;;
727
728 *)
729 if [[ -z $@ ]] ; then
730 useradd -r ${opts} \
731 -c "added by portage for ${PN}" \
732 ${euser} \
733 || die "enewuser failed"
734 else
735 einfo " - Extra: $@"
736 useradd -r ${opts} "$@" \
737 ${euser} \
738 || die "enewuser failed"
739 fi
740 ;;
741 esac
742
743 if [[ ! -e ${ROOT}/${ehome} ]] ; then
744 einfo " - Creating ${ehome} in ${ROOT}"
745 mkdir -p "${ROOT}/${ehome}"
746 chown ${euser} "${ROOT}/${ehome}"
747 chmod 755 "${ROOT}/${ehome}"
748 fi
749
750 export SANDBOX_ON=${oldsandbox}
751}
752
753# @FUNCTION: enewgroup
754# @USAGE: <group> [gid]
755# @DESCRIPTION:
756# This function does not require you to understand how to properly add a
757# group to the system. Just give it a group name to add and enewgroup will
758# do the rest. You may specify the gid for the group or allow the group to
759# allocate the next available one.
760enewgroup() {
761 case ${EBUILD_PHASE} in
762 unpack|compile|test|install)
763 eerror "'enewgroup()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
764 eerror "Package fails at QA and at life. Please file a bug."
765 die "Bad package! enewgroup is only for use in pkg_* functions!"
766 esac
767
768 # get the group
769 local egroup="$1"; shift
770 if [ -z "${egroup}" ]
771 then
772 eerror "No group specified !"
773 die "Cannot call enewgroup without a group"
774 fi
775
776 # see if group already exists
777 if [[ -n $(egetent group "${egroup}") ]]; then
778 return 0
779 fi
780 einfo "Adding group '${egroup}' to your system ..."
781
782 # options to pass to useradd
783 local opts=
784
785 # handle gid
786 local egid="$1"; shift
787 if [ ! -z "${egid}" ]
788 then
789 if [ "${egid}" -gt 0 ]
790 then
791 if [ -z "`egetent group ${egid}`" ]
792 then
793 if [[ "${CHOST}" == *-darwin* ]]; then
794 opts="${opts} ${egid}"
795 else
796 opts="${opts} -g ${egid}"
797 fi
798 else
799 egid="next available; requested gid taken"
800 fi
801 else
802 eerror "Groupid given but is not greater than 0 !"
803 die "${egid} is not a valid GID"
804 fi
805 else
806 egid="next available"
807 fi
808 einfo " - Groupid: ${egid}"
809
810 # handle extra
811 local eextra="$@"
812 opts="${opts} ${eextra}"
813
814 # add the group
815 local oldsandbox="${SANDBOX_ON}"
816 export SANDBOX_ON="0"
817 case ${CHOST} in
818 *-darwin*)
819 if [ ! -z "${eextra}" ];
820 then
821 einfo "Extra options are not supported on Darwin/OS X yet"
822 einfo "Please report the ebuild along with the info below"
823 einfo "eextra: ${eextra}"
824 die "Required function missing"
825 fi
826
827 # If we need the next available
828 case ${egid} in
829 *[!0-9]*) # Non numeric
830 for ((egid = 101; egid <= 999; egid++)); do
831 [[ -z $(egetent group ${egid}) ]] && break
832 done
833 esac
834 dscl . create /groups/${egroup} gid ${egid}
835 dscl . create /groups/${egroup} passwd '*'
836 ;;
837
838 *-freebsd*|*-dragonfly*)
839 case ${egid} in
840 *[!0-9]*) # Non numeric
841 for ((egid = 101; egid <= 999; egid++)); do
842 [[ -z $(egetent group ${egid}) ]] && break
843 done
844 esac
845 pw groupadd ${egroup} -g ${egid} || die "enewgroup failed"
846 ;;
847
848 *-netbsd*)
849 case ${egid} in
850 *[!0-9]*) # Non numeric
851 for ((egid = 101; egid <= 999; egid++)); do
852 [[ -z $(egetent group ${egid}) ]] && break
853 done
854 esac
855 groupadd -g ${egid} ${egroup} || die "enewgroup failed"
856 ;;
857
858 *)
859 # We specify -r so that we get a GID in the system range from login.defs
860 groupadd -r ${opts} ${egroup} || die "enewgroup failed"
861 ;;
862 esac
863 export SANDBOX_ON="${oldsandbox}"
864}
865
866# @FUNCTION: edos2unix 612# @FUNCTION: edos2unix
867# @USAGE: <file> [more files ...] 613# @USAGE: <file> [more files ...]
868# @DESCRIPTION: 614# @DESCRIPTION:
869# A handy replacement for dos2unix, recode, fixdos, etc... This allows you 615# A handy replacement for dos2unix, recode, fixdos, etc... This allows you
870# to remove all of these text utilities from DEPEND variables because this 616# to remove all of these text utilities from DEPEND variables because this
871# is a script based solution. Just give it a list of files to convert and 617# is a script based solution. Just give it a list of files to convert and
872# they will all be changed from the DOS CRLF format to the UNIX LF format. 618# they will all be changed from the DOS CRLF format to the UNIX LF format.
873edos2unix() { 619edos2unix() {
874 echo "$@" | xargs sed -i 's/\r$//' 620 [[ $# -eq 0 ]] && return 0
621 sed -i 's/\r$//' -- "$@" || die
875} 622}
876 623
877# Make a desktop file ! 624# @FUNCTION: make_desktop_entry
878# Great for making those icons in kde/gnome startmenu !
879# Amaze your friends ! Get the women ! Join today !
880#
881# make_desktop_entry(<command>, [name], [icon], [type], [fields]) 625# @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
626# @DESCRIPTION:
627# Make a .desktop file.
882# 628#
629# @CODE
883# binary: what command does the app run with ? 630# binary: what command does the app run with ?
884# name: the name that will show up in the menu 631# name: the name that will show up in the menu
885# icon: give your little like a pretty little icon ... 632# icon: give your little like a pretty little icon ...
886# this can be relative (to /usr/share/pixmaps) or 633# this can be relative (to /usr/share/pixmaps) or
887# a full path to an icon 634# a full path to an icon
888# type: what kind of application is this ? for categories: 635# type: what kind of application is this?
636# for categories:
889# http://standards.freedesktop.org/menu-spec/latest/apa.html 637# http://standards.freedesktop.org/menu-spec/latest/apa.html
638# if unset, function tries to guess from package's category
890# fields: extra fields to append to the desktop file; a printf string 639# fields: extra fields to append to the desktop file; a printf string
640# @CODE
891make_desktop_entry() { 641make_desktop_entry() {
892 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable" 642 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
893 643
894 local exec=${1} 644 local exec=${1}
895 local name=${2:-${PN}} 645 local name=${2:-${PN}}
901 local catmaj=${CATEGORY%%-*} 651 local catmaj=${CATEGORY%%-*}
902 local catmin=${CATEGORY##*-} 652 local catmin=${CATEGORY##*-}
903 case ${catmaj} in 653 case ${catmaj} in
904 app) 654 app)
905 case ${catmin} in 655 case ${catmin} in
906 accessibility) type=Accessibility;; 656 accessibility) type="Utility;Accessibility";;
907 admin) type=System;; 657 admin) type=System;;
908 antivirus) type=System;; 658 antivirus) type=System;;
909 arch) type=Archiving;; 659 arch) type="Utility;Archiving";;
910 backup) type=Archiving;; 660 backup) type="Utility;Archiving";;
911 cdr) type=DiscBurning;; 661 cdr) type="AudioVideo;DiscBurning";;
912 dicts) type=Dictionary;; 662 dicts) type="Office;Dictionary";;
913 doc) type=Documentation;; 663 doc) type=Documentation;;
914 editors) type=TextEditor;; 664 editors) type="Utility;TextEditor";;
915 emacs) type=TextEditor;; 665 emacs) type="Development;TextEditor";;
916 emulation) type=Emulator;; 666 emulation) type="System;Emulator";;
917 laptop) type=HardwareSettings;; 667 laptop) type="Settings;HardwareSettings";;
918 office) type=Office;; 668 office) type=Office;;
919 pda) type=PDA;; 669 pda) type="Office;PDA";;
920 vim) type=TextEditor;; 670 vim) type="Development;TextEditor";;
921 xemacs) type=TextEditor;; 671 xemacs) type="Development;TextEditor";;
922 esac 672 esac
923 ;; 673 ;;
924 674
925 dev) 675 dev)
926 type="Development" 676 type="Development"
1202 # wrap the env here so that the 'insinto' call 952 # wrap the env here so that the 'insinto' call
1203 # doesn't corrupt the env of the caller 953 # doesn't corrupt the env of the caller
1204 insinto /usr/share/pixmaps 954 insinto /usr/share/pixmaps
1205 newins "$@" 955 newins "$@"
1206 ) 956 )
1207}
1208
1209# for internal use only (unpack_pdv and unpack_makeself)
1210find_unpackable_file() {
1211 local src=$1
1212 if [[ -z ${src} ]] ; then
1213 src=${DISTDIR}/${A}
1214 else
1215 if [[ -e ${DISTDIR}/${src} ]] ; then
1216 src=${DISTDIR}/${src}
1217 elif [[ -e ${PWD}/${src} ]] ; then
1218 src=${PWD}/${src}
1219 elif [[ -e ${src} ]] ; then
1220 src=${src}
1221 fi
1222 fi
1223 [[ ! -e ${src} ]] && return 1
1224 echo "${src}"
1225}
1226
1227# @FUNCTION: unpack_pdv
1228# @USAGE: <file to unpack> <size of off_t>
1229# @DESCRIPTION:
1230# Unpack those pesky pdv generated files ...
1231# They're self-unpacking programs with the binary package stuffed in
1232# the middle of the archive. Valve seems to use it a lot ... too bad
1233# it seems to like to segfault a lot :(. So lets take it apart ourselves.
1234#
1235# You have to specify the off_t size ... I have no idea how to extract that
1236# information out of the binary executable myself. Basically you pass in
1237# the size of the off_t type (in bytes) on the machine that built the pdv
1238# archive.
1239#
1240# One way to determine this is by running the following commands:
1241#
1242# @CODE
1243# strings <pdv archive> | grep lseek
1244# strace -elseek <pdv archive>
1245# @CODE
1246#
1247# Basically look for the first lseek command (we do the strings/grep because
1248# sometimes the function call is _llseek or something) and steal the 2nd
1249# parameter. Here is an example:
1250#
1251# @CODE
1252# vapier@vapier 0 pdv_unpack # strings hldsupdatetool.bin | grep lseek
1253# lseek
1254# vapier@vapier 0 pdv_unpack # strace -elseek ./hldsupdatetool.bin
1255# lseek(3, -4, SEEK_END) = 2981250
1256# @CODE
1257#
1258# Thus we would pass in the value of '4' as the second parameter.
1259unpack_pdv() {
1260 local src=$(find_unpackable_file "$1")
1261 local sizeoff_t=$2
1262
1263 [[ -z ${src} ]] && die "Could not locate source for '$1'"
1264 [[ -z ${sizeoff_t} ]] && die "No idea what off_t size was used for this pdv :("
1265
1266 local shrtsrc=$(basename "${src}")
1267 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1268 local metaskip=$(tail -c ${sizeoff_t} "${src}" | hexdump -e \"%i\")
1269 local tailskip=$(tail -c $((${sizeoff_t}*2)) "${src}" | head -c ${sizeoff_t} | hexdump -e \"%i\")
1270
1271 # grab metadata for debug reasons
1272 local metafile=$(emktemp)
1273 tail -c +$((${metaskip}+1)) "${src}" > "${metafile}"
1274
1275 # rip out the final file name from the metadata
1276 local datafile=$(tail -c +$((${metaskip}+1)) "${src}" | strings | head -n 1)
1277 datafile=$(basename "${datafile}")
1278
1279 # now lets uncompress/untar the file if need be
1280 local tmpfile=$(emktemp)
1281 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null | head -c 512 > ${tmpfile}
1282
1283 local iscompressed=$(file -b "${tmpfile}")
1284 if [[ ${iscompressed:0:8} == "compress" ]] ; then
1285 iscompressed=1
1286 mv ${tmpfile}{,.Z}
1287 gunzip ${tmpfile}
1288 else
1289 iscompressed=0
1290 fi
1291 local istar=$(file -b "${tmpfile}")
1292 if [[ ${istar:0:9} == "POSIX tar" ]] ; then
1293 istar=1
1294 else
1295 istar=0
1296 fi
1297
1298 #for some reason gzip dies with this ... dd cant provide buffer fast enough ?
1299 #dd if=${src} ibs=${metaskip} count=1 \
1300 # | dd ibs=${tailskip} skip=1 \
1301 # | gzip -dc \
1302 # > ${datafile}
1303 if [ ${iscompressed} -eq 1 ] ; then
1304 if [ ${istar} -eq 1 ] ; then
1305 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1306 | head -c $((${metaskip}-${tailskip})) \
1307 | tar -xzf -
1308 else
1309 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1310 | head -c $((${metaskip}-${tailskip})) \
1311 | gzip -dc \
1312 > ${datafile}
1313 fi
1314 else
1315 if [ ${istar} -eq 1 ] ; then
1316 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1317 | head -c $((${metaskip}-${tailskip})) \
1318 | tar --no-same-owner -xf -
1319 else
1320 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1321 | head -c $((${metaskip}-${tailskip})) \
1322 > ${datafile}
1323 fi
1324 fi
1325 true
1326 #[ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1327 #assert "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1328}
1329
1330# @FUNCTION: unpack_makeself
1331# @USAGE: [file to unpack] [offset] [tail|dd]
1332# @DESCRIPTION:
1333# Unpack those pesky makeself generated files ...
1334# They're shell scripts with the binary package tagged onto
1335# the end of the archive. Loki utilized the format as does
1336# many other game companies.
1337#
1338# If the file is not specified, then ${A} is used. If the
1339# offset is not specified then we will attempt to extract
1340# the proper offset from the script itself.
1341unpack_makeself() {
1342 local src_input=${1:-${A}}
1343 local src=$(find_unpackable_file "${src_input}")
1344 local skip=$2
1345 local exe=$3
1346
1347 [[ -z ${src} ]] && die "Could not locate source for '${src_input}'"
1348
1349 local shrtsrc=$(basename "${src}")
1350 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1351 if [[ -z ${skip} ]] ; then
1352 local ver=$(grep -m1 -a '#.*Makeself' "${src}" | awk '{print $NF}')
1353 local skip=0
1354 exe=tail
1355 case ${ver} in
1356 1.5.*|1.6.0-nv) # tested 1.5.{3,4,5} ... guessing 1.5.x series is same
1357 skip=$(grep -a ^skip= "${src}" | cut -d= -f2)
1358 ;;
1359 2.0|2.0.1)
1360 skip=$(grep -a ^$'\t'tail "${src}" | awk '{print $2}' | cut -b2-)
1361 ;;
1362 2.1.1)
1363 skip=$(grep -a ^offset= "${src}" | awk '{print $2}' | cut -b2-)
1364 (( skip++ ))
1365 ;;
1366 2.1.2)
1367 skip=$(grep -a ^offset= "${src}" | awk '{print $3}' | head -n 1)
1368 (( skip++ ))
1369 ;;
1370 2.1.3)
1371 skip=`grep -a ^offset= "${src}" | awk '{print $3}'`
1372 (( skip++ ))
1373 ;;
1374 2.1.4|2.1.5)
1375 skip=$(grep -a offset=.*head.*wc "${src}" | awk '{print $3}' | head -n 1)
1376 skip=$(head -n ${skip} "${src}" | wc -c)
1377 exe="dd"
1378 ;;
1379 *)
1380 eerror "I'm sorry, but I was unable to support the Makeself file."
1381 eerror "The version I detected was '${ver}'."
1382 eerror "Please file a bug about the file ${shrtsrc} at"
1383 eerror "http://bugs.gentoo.org/ so that support can be added."
1384 die "makeself version '${ver}' not supported"
1385 ;;
1386 esac
1387 debug-print "Detected Makeself version ${ver} ... using ${skip} as offset"
1388 fi
1389 case ${exe} in
1390 tail) exe="tail -n +${skip} '${src}'";;
1391 dd) exe="dd ibs=${skip} skip=1 if='${src}'";;
1392 *) die "makeself cant handle exe '${exe}'"
1393 esac
1394
1395 # lets grab the first few bytes of the file to figure out what kind of archive it is
1396 local tmpfile=$(emktemp)
1397 eval ${exe} 2>/dev/null | head -c 512 > "${tmpfile}"
1398 local filetype=$(file -b "${tmpfile}")
1399 case ${filetype} in
1400 *tar\ archive*)
1401 eval ${exe} | tar --no-same-owner -xf -
1402 ;;
1403 bzip2*)
1404 eval ${exe} | bzip2 -dc | tar --no-same-owner -xf -
1405 ;;
1406 gzip*)
1407 eval ${exe} | tar --no-same-owner -xzf -
1408 ;;
1409 compress*)
1410 eval ${exe} | gunzip | tar --no-same-owner -xf -
1411 ;;
1412 *)
1413 eerror "Unknown filetype \"${filetype}\" ?"
1414 false
1415 ;;
1416 esac
1417 assert "failure unpacking (${filetype}) makeself ${shrtsrc} ('${ver}' +${skip})"
1418}
1419
1420# @FUNCTION: check_license
1421# @USAGE: [license]
1422# @DESCRIPTION:
1423# Display a license for user to accept. If no license is
1424# specified, then ${LICENSE} is used.
1425check_license() {
1426 local lic=$1
1427 if [ -z "${lic}" ] ; then
1428 lic="${PORTDIR}/licenses/${LICENSE}"
1429 else
1430 if [ -e "${PORTDIR}/licenses/${lic}" ] ; then
1431 lic="${PORTDIR}/licenses/${lic}"
1432 elif [ -e "${PWD}/${lic}" ] ; then
1433 lic="${PWD}/${lic}"
1434 elif [ -e "${lic}" ] ; then
1435 lic="${lic}"
1436 fi
1437 fi
1438 local l="`basename ${lic}`"
1439
1440 # here is where we check for the licenses the user already
1441 # accepted ... if we don't find a match, we make the user accept
1442 local alic
1443 eshopts_push -o noglob # so that bash doesn't expand "*"
1444 for alic in ${ACCEPT_LICENSE} ; do
1445 if [[ ${alic} == ${l} ]]; then
1446 eshopts_pop
1447 return 0
1448 fi
1449 done
1450 eshopts_pop
1451 [ ! -f "${lic}" ] && die "Could not find requested license ${lic}"
1452
1453 local licmsg=$(emktemp)
1454 cat <<-EOF > ${licmsg}
1455 **********************************************************
1456 The following license outlines the terms of use of this
1457 package. You MUST accept this license for installation to
1458 continue. When you are done viewing, hit 'q'. If you
1459 CTRL+C out of this, the install will not run!
1460 **********************************************************
1461
1462 EOF
1463 cat ${lic} >> ${licmsg}
1464 ${PAGER:-less} ${licmsg} || die "Could not execute pager (${PAGER}) to accept ${lic}"
1465 einfon "Do you accept the terms of this license (${l})? [yes/no] "
1466 read alic
1467 case ${alic} in
1468 yes|Yes|y|Y)
1469 return 0
1470 ;;
1471 *)
1472 echo;echo;echo
1473 eerror "You MUST accept the license to continue! Exiting!"
1474 die "Failed to accept license"
1475 ;;
1476 esac
1477}
1478
1479# @FUNCTION: cdrom_get_cds
1480# @USAGE: <file on cd1> [file on cd2] [file on cd3] [...]
1481# @DESCRIPTION:
1482# Aquire cd(s) for those lovely cd-based emerges. Yes, this violates
1483# the whole 'non-interactive' policy, but damnit I want CD support !
1484#
1485# With these cdrom functions we handle all the user interaction and
1486# standardize everything. All you have to do is call cdrom_get_cds()
1487# and when the function returns, you can assume that the cd has been
1488# found at CDROM_ROOT.
1489#
1490# The function will attempt to locate a cd based upon a file that is on
1491# the cd. The more files you give this function, the more cds
1492# the cdrom functions will handle.
1493#
1494# Normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2',
1495# etc... If you want to give the cds better names, then just export
1496# the appropriate CDROM_NAME variable before calling cdrom_get_cds().
1497# Use CDROM_NAME for one cd, or CDROM_NAME_# for multiple cds. You can
1498# also use the CDROM_NAME_SET bash array.
1499#
1500# For those multi cd ebuilds, see the cdrom_load_next_cd() function.
1501cdrom_get_cds() {
1502 # first we figure out how many cds we're dealing with by
1503 # the # of files they gave us
1504 local cdcnt=0
1505 local f=
1506 for f in "$@" ; do
1507 ((++cdcnt))
1508 export CDROM_CHECK_${cdcnt}="$f"
1509 done
1510 export CDROM_TOTAL_CDS=${cdcnt}
1511 export CDROM_CURRENT_CD=1
1512
1513 # now we see if the user gave use CD_ROOT ...
1514 # if they did, let's just believe them that it's correct
1515 if [[ -n ${CD_ROOT}${CD_ROOT_1} ]] ; then
1516 local var=
1517 cdcnt=0
1518 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1519 ((++cdcnt))
1520 var="CD_ROOT_${cdcnt}"
1521 [[ -z ${!var} ]] && var="CD_ROOT"
1522 if [[ -z ${!var} ]] ; then
1523 eerror "You must either use just the CD_ROOT"
1524 eerror "or specify ALL the CD_ROOT_X variables."
1525 eerror "In this case, you will need ${CDROM_TOTAL_CDS} CD_ROOT_X variables."
1526 die "could not locate CD_ROOT_${cdcnt}"
1527 fi
1528 done
1529 export CDROM_ROOT=${CD_ROOT_1:-${CD_ROOT}}
1530 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1531 export CDROM_SET=-1
1532 for f in ${CDROM_CHECK_1//:/ } ; do
1533 ((++CDROM_SET))
1534 [[ -e ${CDROM_ROOT}/${f} ]] && break
1535 done
1536 export CDROM_MATCH=${f}
1537 return
1538 fi
1539
1540 # User didn't help us out so lets make sure they know they can
1541 # simplify the whole process ...
1542 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1543 einfo "This ebuild will need the ${CDROM_NAME:-cdrom for ${PN}}"
1544 echo
1545 einfo "If you do not have the CD, but have the data files"
1546 einfo "mounted somewhere on your filesystem, just export"
1547 einfo "the variable CD_ROOT so that it points to the"
1548 einfo "directory containing the files."
1549 echo
1550 einfo "For example:"
1551 einfo "export CD_ROOT=/mnt/cdrom"
1552 echo
1553 else
1554 if [[ -n ${CDROM_NAME_SET} ]] ; then
1555 # Translate the CDROM_NAME_SET array into CDROM_NAME_#
1556 cdcnt=0
1557 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1558 ((++cdcnt))
1559 export CDROM_NAME_${cdcnt}="${CDROM_NAME_SET[$((${cdcnt}-1))]}"
1560 done
1561 fi
1562
1563 einfo "This package will need access to ${CDROM_TOTAL_CDS} cds."
1564 cdcnt=0
1565 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1566 ((++cdcnt))
1567 var="CDROM_NAME_${cdcnt}"
1568 [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}"
1569 done
1570 echo
1571 einfo "If you do not have the CDs, but have the data files"
1572 einfo "mounted somewhere on your filesystem, just export"
1573 einfo "the following variables so they point to the right place:"
1574 einfon ""
1575 cdcnt=0
1576 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1577 ((++cdcnt))
1578 echo -n " CD_ROOT_${cdcnt}"
1579 done
1580 echo
1581 einfo "Or, if you have all the files in the same place, or"
1582 einfo "you only have one cdrom, you can export CD_ROOT"
1583 einfo "and that place will be used as the same data source"
1584 einfo "for all the CDs."
1585 echo
1586 einfo "For example:"
1587 einfo "export CD_ROOT_1=/mnt/cdrom"
1588 echo
1589 fi
1590
1591 export CDROM_SET=""
1592 export CDROM_CURRENT_CD=0
1593 cdrom_load_next_cd
1594}
1595
1596# @FUNCTION: cdrom_load_next_cd
1597# @DESCRIPTION:
1598# Some packages are so big they come on multiple CDs. When you're done reading
1599# files off a CD and want access to the next one, just call this function.
1600# Again, all the messy details of user interaction are taken care of for you.
1601# Once this returns, just read the variable CDROM_ROOT for the location of the
1602# mounted CD. Note that you can only go forward in the CD list, so make sure
1603# you only call this function when you're done using the current CD.
1604cdrom_load_next_cd() {
1605 local var
1606 ((++CDROM_CURRENT_CD))
1607
1608 unset CDROM_ROOT
1609 var=CD_ROOT_${CDROM_CURRENT_CD}
1610 [[ -z ${!var} ]] && var="CD_ROOT"
1611 if [[ -z ${!var} ]] ; then
1612 var="CDROM_CHECK_${CDROM_CURRENT_CD}"
1613 _cdrom_locate_file_on_cd ${!var}
1614 else
1615 export CDROM_ROOT=${!var}
1616 fi
1617
1618 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1619}
1620
1621# this is used internally by the cdrom_get_cds() and cdrom_load_next_cd()
1622# functions. this should *never* be called from an ebuild.
1623# all it does is try to locate a give file on a cd ... if the cd isn't
1624# found, then a message asking for the user to insert the cdrom will be
1625# displayed and we'll hang out here until:
1626# (1) the file is found on a mounted cdrom
1627# (2) the user hits CTRL+C
1628_cdrom_locate_file_on_cd() {
1629 local mline=""
1630 local showedmsg=0 showjolietmsg=0
1631
1632 while [[ -z ${CDROM_ROOT} ]] ; do
1633 local i=0
1634 local -a cdset=(${*//:/ })
1635 if [[ -n ${CDROM_SET} ]] ; then
1636 cdset=(${cdset[${CDROM_SET}]})
1637 fi
1638
1639 while [[ -n ${cdset[${i}]} ]] ; do
1640 local dir=$(dirname ${cdset[${i}]})
1641 local file=$(basename ${cdset[${i}]})
1642
1643 local point= node= fs= foo=
1644 while read point node fs foo ; do
1645 [[ " cd9660 iso9660 udf " != *" ${fs} "* ]] && \
1646 ! [[ ${fs} == "subfs" && ",${opts}," == *",fs=cdfss,"* ]] \
1647 && continue
1648 point=${point//\040/ }
1649 [[ ! -d ${point}/${dir} ]] && continue
1650 [[ -z $(find "${point}/${dir}" -maxdepth 1 -iname "${file}") ]] && continue
1651 export CDROM_ROOT=${point}
1652 export CDROM_SET=${i}
1653 export CDROM_MATCH=${cdset[${i}]}
1654 return
1655 done <<< "$(get_mounts)"
1656
1657 ((++i))
1658 done
1659
1660 echo
1661 if [[ ${showedmsg} -eq 0 ]] ; then
1662 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1663 if [[ -z ${CDROM_NAME} ]] ; then
1664 einfo "Please insert+mount the cdrom for ${PN} now !"
1665 else
1666 einfo "Please insert+mount the ${CDROM_NAME} cdrom now !"
1667 fi
1668 else
1669 if [[ -z ${CDROM_NAME_1} ]] ; then
1670 einfo "Please insert+mount cd #${CDROM_CURRENT_CD} for ${PN} now !"
1671 else
1672 local var="CDROM_NAME_${CDROM_CURRENT_CD}"
1673 einfo "Please insert+mount the ${!var} cdrom now !"
1674 fi
1675 fi
1676 showedmsg=1
1677 fi
1678 einfo "Press return to scan for the cd again"
1679 einfo "or hit CTRL+C to abort the emerge."
1680 echo
1681 if [[ ${showjolietmsg} -eq 0 ]] ; then
1682 showjolietmsg=1
1683 else
1684 ewarn "If you are having trouble with the detection"
1685 ewarn "of your CD, it is possible that you do not have"
1686 ewarn "Joliet support enabled in your kernel. Please"
1687 ewarn "check that CONFIG_JOLIET is enabled in your kernel."
1688 ebeep 5
1689 fi
1690 read || die "something is screwed with your system"
1691 done
1692} 957}
1693 958
1694# @FUNCTION: strip-linguas 959# @FUNCTION: strip-linguas
1695# @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>] 960# @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1696# @DESCRIPTION: 961# @DESCRIPTION:
1713 else 978 else
1714 newls="" 979 newls=""
1715 fi 980 fi
1716 for f in $(find "$d" -name '*.po' -exec basename {} .po ';') ; do 981 for f in $(find "$d" -name '*.po' -exec basename {} .po ';') ; do
1717 if [[ ${op} == "-i" ]] ; then 982 if [[ ${op} == "-i" ]] ; then
1718 hasq ${f} ${ls} && newls="${newls} ${f}" 983 has ${f} ${ls} && newls="${newls} ${f}"
1719 else 984 else
1720 hasq ${f} ${ls} || newls="${newls} ${f}" 985 has ${f} ${ls} || newls="${newls} ${f}"
1721 fi 986 fi
1722 done 987 done
1723 ls=${newls} 988 ls=${newls}
1724 done 989 done
1725 else 990 else
1727 fi 992 fi
1728 993
1729 nols="" 994 nols=""
1730 newls="" 995 newls=""
1731 for f in ${LINGUAS} ; do 996 for f in ${LINGUAS} ; do
1732 if hasq ${f} ${ls} ; then 997 if has ${f} ${ls} ; then
1733 newls="${newls} ${f}" 998 newls="${newls} ${f}"
1734 else 999 else
1735 nols="${nols} ${f}" 1000 nols="${nols} ${f}"
1736 fi 1001 fi
1737 done 1002 done
1792 ewarn "the libraries are not being removed. You need to run revdep-rebuild" 1057 ewarn "the libraries are not being removed. You need to run revdep-rebuild"
1793 ewarn "in order to remove these old dependencies. If you do not have this" 1058 ewarn "in order to remove these old dependencies. If you do not have this"
1794 ewarn "helper program, simply emerge the 'gentoolkit' package." 1059 ewarn "helper program, simply emerge the 'gentoolkit' package."
1795 ewarn 1060 ewarn
1796 fi 1061 fi
1062 # temp hack for #348634 #357225
1063 [[ ${PN} == "mpfr" ]] && lib=${lib##*/}
1797 ewarn " # revdep-rebuild --library '${lib}'" 1064 ewarn " # revdep-rebuild --library '${lib}'"
1798 done 1065 done
1799 if [[ ${notice} -eq 1 ]] ; then 1066 if [[ ${notice} -eq 1 ]] ; then
1800 ewarn 1067 ewarn
1801 ewarn "Once you've finished running revdep-rebuild, it should be safe to" 1068 ewarn "Once you've finished running revdep-rebuild, it should be safe to"
1948 else 1215 else
1949 newbin "${tmpwrapper}" "${wrapper}" || die 1216 newbin "${tmpwrapper}" "${wrapper}" || die
1950 fi 1217 fi
1951} 1218}
1952 1219
1953# @FUNCTION: prepalldocs
1954# @USAGE:
1955# @DESCRIPTION:
1956# Compress files in /usr/share/doc which are not already
1957# compressed, excluding /usr/share/doc/${PF}/html.
1958# Uses the ecompressdir to do the compression.
1959# 2009-02-18 by betelgeuse:
1960# Commented because ecompressdir is even more internal to
1961# Portage than prepalldocs (it's not even mentioned in man 5
1962# ebuild). Please submit a better version for review to gentoo-dev
1963# if you want prepalldocs here.
1964#prepalldocs() {
1965# if [[ -n $1 ]] ; then
1966# ewarn "prepalldocs: invalid usage; takes no arguments"
1967# fi
1968
1969# cd "${D}"
1970# [[ -d usr/share/doc ]] || return 0
1971
1972# find usr/share/doc -exec gzip {} +
1973# ecompressdir --ignore /usr/share/doc/${PF}/html
1974# ecompressdir --queue /usr/share/doc
1975#}
1976
1977# @FUNCTION: path_exists 1220# @FUNCTION: path_exists
1978# @USAGE: [-a|-o] <paths> 1221# @USAGE: [-a|-o] <paths>
1979# @DESCRIPTION: 1222# @DESCRIPTION:
1980# Check if the specified paths exist. Works for all types of paths 1223# Check if the specified paths exist. Works for all types of paths
1981# (files/dirs/etc...). The -a and -o flags control the requirements 1224# (files/dirs/etc...). The -a and -o flags control the requirements
2000 case ${opt} in 1243 case ${opt} in
2001 -a) return $(( r != 0 )) ;; 1244 -a) return $(( r != 0 )) ;;
2002 -o) return $(( r == $# )) ;; 1245 -o) return $(( r == $# )) ;;
2003 esac 1246 esac
2004} 1247}
1248
1249# @FUNCTION: in_iuse
1250# @USAGE: <flag>
1251# @DESCRIPTION:
1252# Determines whether the given flag is in IUSE. Strips IUSE default prefixes
1253# as necessary.
1254#
1255# Note that this function should not be used in the global scope.
1256in_iuse() {
1257 debug-print-function ${FUNCNAME} "${@}"
1258 [[ ${#} -eq 1 ]] || die "Invalid args to ${FUNCNAME}()"
1259
1260 local flag=${1}
1261 local liuse=( ${IUSE} )
1262
1263 has "${flag}" "${liuse[@]#[+-]}"
1264}
1265
1266# @FUNCTION: use_if_iuse
1267# @USAGE: <flag>
1268# @DESCRIPTION:
1269# Return true if the given flag is in USE and IUSE.
1270#
1271# Note that this function should not be used in the global scope.
1272use_if_iuse() {
1273 in_iuse $1 || return 1
1274 use $1
1275}
1276
1277# @FUNCTION: usex
1278# @USAGE: <USE flag> [true output] [false output] [true suffix] [false suffix]
1279# @DESCRIPTION:
1280# If USE flag is set, echo [true output][true suffix] (defaults to "yes"),
1281# otherwise echo [false output][false suffix] (defaults to "no").
1282usex() { use "$1" && echo "${2-yes}$4" || echo "${3-no}$5" ; } #382963
1283
1284check_license() { die "you no longer need this as portage supports ACCEPT_LICENSE itself"; }
1285
1286fi

Legend:
Removed from v.1.353  
changed lines
  Added in v.1.386

  ViewVC Help
Powered by ViewVC 1.1.20