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

Diff of /eclass/eutils.eclass

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

Revision 1.363 Revision 1.389
1# Copyright 1999-2011 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.363 2011/09/12 20:44:01 mgorny Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.389 2012/04/15 20:02:43 vapier 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
70# implementation if available. Reuses PORTAGE_ELOG_CLASSES as set by the dev 73# implementation if available. Reuses PORTAGE_ELOG_CLASSES as set by the dev
71# profile. 74# profile.
72if ! declare -F eqawarn >/dev/null ; then 75if ! declare -F eqawarn >/dev/null ; then
73 eqawarn() { 76 eqawarn() {
74 has qa ${PORTAGE_ELOG_CLASSES} && ewarn "$@" 77 has qa ${PORTAGE_ELOG_CLASSES} && ewarn "$@"
78 :
75 } 79 }
76fi 80fi
77 81
78# @FUNCTION: ecvs_clean 82# @FUNCTION: ecvs_clean
79# @USAGE: [list of dirs] 83# @USAGE: [list of dirs]
94esvn_clean() { 98esvn_clean() {
95 [[ -z $* ]] && set -- . 99 [[ -z $* ]] && set -- .
96 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf 100 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
97} 101}
98 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
99# @FUNCTION: eshopts_push 151# @FUNCTION: eshopts_push
100# @USAGE: [options to `set` or `shopt`] 152# @USAGE: [options to `set` or `shopt`]
101# @DESCRIPTION: 153# @DESCRIPTION:
102# 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.
103# 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
108# 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.
109# 161#
110# 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
111# 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:
112# @CODE 164# @CODE
113# eshopts_push -o noglob 165# eshopts_push -s noglob
114# for x in ${foo} ; do 166# for x in ${foo} ; do
115# if ...some check... ; then 167# if ...some check... ; then
116# eshopts_pop 168# eshopts_pop
117# return 0 169# return 0
118# fi 170# fi
119# done 171# done
120# eshopts_pop 172# eshopts_pop
121# @CODE 173# @CODE
122eshopts_push() { 174eshopts_push() {
123 # have to assume __ESHOPTS_SAVE__ isn't screwed with
124 # as a `declare -a` here will reset its value
125 local i=${#__ESHOPTS_SAVE__[@]}
126 if [[ $1 == -[su] ]] ; then 175 if [[ $1 == -[su] ]] ; then
127 __ESHOPTS_SAVE__[$i]=$(shopt -p) 176 estack_push eshopts "$(shopt -p)"
128 [[ $# -eq 0 ]] && return 0 177 [[ $# -eq 0 ]] && return 0
129 shopt "$@" || die "eshopts_push: bad options to shopt: $*" 178 shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*"
130 else 179 else
131 __ESHOPTS_SAVE__[$i]=$- 180 estack_push eshopts $-
132 [[ $# -eq 0 ]] && return 0 181 [[ $# -eq 0 ]] && return 0
133 set "$@" || die "eshopts_push: bad options to set: $*" 182 set "$@" || die "${FUNCNAME}: bad options to set: $*"
134 fi 183 fi
135} 184}
136 185
137# @FUNCTION: eshopts_pop 186# @FUNCTION: eshopts_pop
138# @USAGE: 187# @USAGE:
139# @DESCRIPTION: 188# @DESCRIPTION:
140# Restore the shell options to the state saved with the corresponding 189# Restore the shell options to the state saved with the corresponding
141# eshopts_push call. See that function for more details. 190# eshopts_push call. See that function for more details.
142eshopts_pop() { 191eshopts_pop() {
143 [[ $# -ne 0 ]] && die "eshopts_pop takes no arguments" 192 local s
144 local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 )) 193 estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
145 [[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
146 local s=${__ESHOPTS_SAVE__[$i]}
147 unset __ESHOPTS_SAVE__[$i]
148 if [[ ${s} == "shopt -"* ]] ; then 194 if [[ ${s} == "shopt -"* ]] ; then
149 eval "${s}" || die "eshopts_pop: sanity: invalid shopt options: ${s}" 195 eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}"
150 else 196 else
151 set +$- || die "eshopts_pop: sanity: invalid shell settings: $-" 197 set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-"
152 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}"
153 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}"
154} 221}
155 222
156# @VARIABLE: EPATCH_SOURCE 223# @VARIABLE: EPATCH_SOURCE
157# @DESCRIPTION: 224# @DESCRIPTION:
158# Default directory to search for patches. 225# Default directory to search for patches.
335 local STDERR_TARGET="${T}/${patchname}.out" 402 local STDERR_TARGET="${T}/${patchname}.out"
336 if [[ -e ${STDERR_TARGET} ]] ; then 403 if [[ -e ${STDERR_TARGET} ]] ; then
337 STDERR_TARGET="${T}/${patchname}-$$.out" 404 STDERR_TARGET="${T}/${patchname}-$$.out"
338 fi 405 fi
339 406
340 printf "***** %s *****\n\n" "${patchname}" > "${STDERR_TARGET}" 407 printf "***** %s *****\nPWD: %s\n\n" "${patchname}" "${PWD}" > "${STDERR_TARGET}"
341 408
342 # Decompress the patch if need be 409 # Decompress the patch if need be
343 local count=0 410 local count=0
344 local PATCH_TARGET 411 local PATCH_TARGET
345 if [[ -n ${PIPE_CMD} ]] ; then 412 if [[ -n ${PIPE_CMD} ]] ; then
373 eqawarn " In the future this will cause a failure." 440 eqawarn " In the future this will cause a failure."
374 eqawarn "${rel_paths}" 441 eqawarn "${rel_paths}"
375 fi 442 fi
376 443
377 # 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
378 while [[ ${count} -lt 5 ]] ; do 446 while [[ ${count} -lt 5 ]] ; do
447 patch_cmd="${BASH_ALIASES[patch]:-patch} -p${count} ${EPATCH_OPTS}"
448
379 # Generate some useful debug info ... 449 # Generate some useful debug info ...
380 ( 450 (
381 _epatch_draw_line "***** ${patchname} *****" 451 _epatch_draw_line "***** ${patchname} *****"
382 echo 452 echo
383 echo "PATCH COMMAND: patch -p${count} ${EPATCH_OPTS} < '${PATCH_TARGET}'" 453 echo "PATCH COMMAND: ${patch_cmd} < '${PATCH_TARGET}'"
384 echo 454 echo
385 _epatch_draw_line "***** ${patchname} *****" 455 _epatch_draw_line "***** ${patchname} *****"
386 patch -p${count} ${EPATCH_OPTS} --dry-run -f < "${PATCH_TARGET}" 2>&1 456 ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
387 ret=$? 457 ret=$?
388 echo 458 echo
389 echo "patch program exited with status ${ret}" 459 echo "patch program exited with status ${ret}"
390 exit ${ret} 460 exit ${ret}
391 ) >> "${STDERR_TARGET}" 461 ) >> "${STDERR_TARGET}"
395 _epatch_draw_line "***** ${patchname} *****" 465 _epatch_draw_line "***** ${patchname} *****"
396 echo 466 echo
397 echo "ACTUALLY APPLYING ${patchname} ..." 467 echo "ACTUALLY APPLYING ${patchname} ..."
398 echo 468 echo
399 _epatch_draw_line "***** ${patchname} *****" 469 _epatch_draw_line "***** ${patchname} *****"
400 patch -p${count} ${EPATCH_OPTS} < "${PATCH_TARGET}" 2>&1 470 ${patch_cmd} < "${PATCH_TARGET}" 2>&1
401 ret=$? 471 ret=$?
402 echo 472 echo
403 echo "patch program exited with status ${ret}" 473 echo "patch program exited with status ${ret}"
404 exit ${ret} 474 exit ${ret}
405 ) >> "${STDERR_TARGET}" 475 ) >> "${STDERR_TARGET}"
432 eerror " ${STDERR_TARGET}" 502 eerror " ${STDERR_TARGET}"
433 echo 503 echo
434 die "Failed Patch: ${patchname}!" 504 die "Failed Patch: ${patchname}!"
435 fi 505 fi
436 506
437 # if everything worked, delete the patch log 507 # if everything worked, delete the full debug patch log
438 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
439 eend 0 517 eend 0
440 done 518 done
441 519
442 [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching" 520 [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
443 : # everything worked 521 : # everything worked
447# @USAGE: 525# @USAGE:
448# @DESCRIPTION: 526# @DESCRIPTION:
449# Applies user-provided patches to the source tree. The patches are 527# Applies user-provided patches to the source tree. The patches are
450# taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>/, where the first 528# taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>/, where the first
451# of these three directories to exist will be the one to use, ignoring 529# of these three directories to exist will be the one to use, ignoring
452# any more general directories which might exist as well. 530# any more general directories which might exist as well. They must end
531# in ".patch" to be applied.
453# 532#
454# User patches are intended for quick testing of patches without ebuild 533# User patches are intended for quick testing of patches without ebuild
455# modifications, as well as for permanent customizations a user might 534# modifications, as well as for permanent customizations a user might
456# desire. Obviously, there can be no official support for arbitrarily 535# desire. Obviously, there can be no official support for arbitrarily
457# patched ebuilds. So whenever a build log in a bug report mentions that 536# patched ebuilds. So whenever a build log in a bug report mentions that
471# autotool input files as well. 550# autotool input files as well.
472epatch_user() { 551epatch_user() {
473 [[ $# -ne 0 ]] && die "epatch_user takes no options" 552 [[ $# -ne 0 ]] && die "epatch_user takes no options"
474 553
475 # Allow multiple calls to this function; ignore all but the first 554 # Allow multiple calls to this function; ignore all but the first
476 local applied="${T}/epatch_user.applied" 555 local applied="${T}/epatch_user.log"
477 [[ -e ${applied} ]] && return 2 556 [[ -e ${applied} ]] && return 2
478 557
479 # don't clobber any EPATCH vars that the parent might want 558 # don't clobber any EPATCH vars that the parent might want
480 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches 559 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
481 for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do 560 for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}; do
482 EPATCH_SOURCE=${base}/${CTARGET}/${check} 561 EPATCH_SOURCE=${base}/${CTARGET}/${check}
483 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check} 562 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
484 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check} 563 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
485 if [[ -d ${EPATCH_SOURCE} ]] ; then 564 if [[ -d ${EPATCH_SOURCE} ]] ; then
486 EPATCH_SOURCE=${EPATCH_SOURCE} \ 565 EPATCH_SOURCE=${EPATCH_SOURCE} \
529 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX 608 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
530 fi 609 fi
531 fi 610 fi
532} 611}
533 612
534# @FUNCTION: egetent
535# @USAGE: <database> <key>
536# @MAINTAINER:
537# base-system@gentoo.org (Linux)
538# Joe Jezak <josejx@gmail.com> (OS X)
539# usata@gentoo.org (OS X)
540# Aaron Walker <ka0ttic@gentoo.org> (FreeBSD)
541# @DESCRIPTION:
542# Small wrapper for getent (Linux),
543# nidump (< Mac OS X 10.5), dscl (Mac OS X 10.5),
544# and pw (FreeBSD) used in enewuser()/enewgroup()
545egetent() {
546 case ${CHOST} in
547 *-darwin[678])
548 case "$2" in
549 *[!0-9]*) # Non numeric
550 nidump $1 . | awk -F":" "{ if (\$1 ~ /^$2\$/) {print \$0;exit;} }"
551 ;;
552 *) # Numeric
553 nidump $1 . | awk -F":" "{ if (\$3 == $2) {print \$0;exit;} }"
554 ;;
555 esac
556 ;;
557 *-darwin*)
558 local mytype=$1
559 [[ "passwd" == $mytype ]] && mytype="Users"
560 [[ "group" == $mytype ]] && mytype="Groups"
561 case "$2" in
562 *[!0-9]*) # Non numeric
563 dscl . -read /$mytype/$2 2>/dev/null |grep RecordName
564 ;;
565 *) # Numeric
566 local mykey="UniqueID"
567 [[ $mytype == "Groups" ]] && mykey="PrimaryGroupID"
568 dscl . -search /$mytype $mykey $2 2>/dev/null
569 ;;
570 esac
571 ;;
572 *-freebsd*|*-dragonfly*)
573 local opts action="user"
574 [[ $1 == "passwd" ]] || action="group"
575
576 # lookup by uid/gid
577 if [[ $2 == [[:digit:]]* ]] ; then
578 [[ ${action} == "user" ]] && opts="-u" || opts="-g"
579 fi
580
581 pw show ${action} ${opts} "$2" -q
582 ;;
583 *-netbsd*|*-openbsd*)
584 grep "$2:\*:" /etc/$1
585 ;;
586 *)
587 type -p nscd >& /dev/null && nscd -i "$1"
588 getent "$1" "$2"
589 ;;
590 esac
591}
592
593# @FUNCTION: enewuser
594# @USAGE: <user> [uid] [shell] [homedir] [groups] [params]
595# @DESCRIPTION:
596# Same as enewgroup, you are not required to understand how to properly add
597# a user to the system. The only required parameter is the username.
598# Default uid is (pass -1 for this) next available, default shell is
599# /bin/false, default homedir is /dev/null, there are no default groups,
600# and default params sets the comment as 'added by portage for ${PN}'.
601enewuser() {
602 case ${EBUILD_PHASE} in
603 unpack|compile|test|install)
604 eerror "'enewuser()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
605 eerror "Package fails at QA and at life. Please file a bug."
606 die "Bad package! enewuser is only for use in pkg_* functions!"
607 esac
608
609 # get the username
610 local euser=$1; shift
611 if [[ -z ${euser} ]] ; then
612 eerror "No username specified !"
613 die "Cannot call enewuser without a username"
614 fi
615
616 # lets see if the username already exists
617 if [[ -n $(egetent passwd "${euser}") ]] ; then
618 return 0
619 fi
620 einfo "Adding user '${euser}' to your system ..."
621
622 # options to pass to useradd
623 local opts=
624
625 # handle uid
626 local euid=$1; shift
627 if [[ -n ${euid} && ${euid} != -1 ]] ; then
628 if [[ ${euid} -gt 0 ]] ; then
629 if [[ -n $(egetent passwd ${euid}) ]] ; then
630 euid="next"
631 fi
632 else
633 eerror "Userid given but is not greater than 0 !"
634 die "${euid} is not a valid UID"
635 fi
636 else
637 euid="next"
638 fi
639 if [[ ${euid} == "next" ]] ; then
640 for ((euid = 101; euid <= 999; euid++)); do
641 [[ -z $(egetent passwd ${euid}) ]] && break
642 done
643 fi
644 opts="${opts} -u ${euid}"
645 einfo " - Userid: ${euid}"
646
647 # handle shell
648 local eshell=$1; shift
649 if [[ ! -z ${eshell} ]] && [[ ${eshell} != "-1" ]] ; then
650 if [[ ! -e ${ROOT}${eshell} ]] ; then
651 eerror "A shell was specified but it does not exist !"
652 die "${eshell} does not exist in ${ROOT}"
653 fi
654 if [[ ${eshell} == */false || ${eshell} == */nologin ]] ; then
655 eerror "Do not specify ${eshell} yourself, use -1"
656 die "Pass '-1' as the shell parameter"
657 fi
658 else
659 for shell in /sbin/nologin /usr/sbin/nologin /bin/false /usr/bin/false /dev/null ; do
660 [[ -x ${ROOT}${shell} ]] && break
661 done
662
663 if [[ ${shell} == "/dev/null" ]] ; then
664 eerror "Unable to identify the shell to use, proceeding with userland default."
665 case ${USERLAND} in
666 GNU) shell="/bin/false" ;;
667 BSD) shell="/sbin/nologin" ;;
668 Darwin) shell="/usr/sbin/nologin" ;;
669 *) die "Unable to identify the default shell for userland ${USERLAND}"
670 esac
671 fi
672
673 eshell=${shell}
674 fi
675 einfo " - Shell: ${eshell}"
676 opts="${opts} -s ${eshell}"
677
678 # handle homedir
679 local ehome=$1; shift
680 if [[ -z ${ehome} ]] || [[ ${ehome} == "-1" ]] ; then
681 ehome="/dev/null"
682 fi
683 einfo " - Home: ${ehome}"
684 opts="${opts} -d ${ehome}"
685
686 # handle groups
687 local egroups=$1; shift
688 if [[ ! -z ${egroups} ]] ; then
689 local oldifs=${IFS}
690 local defgroup="" exgroups=""
691
692 export IFS=","
693 for g in ${egroups} ; do
694 export IFS=${oldifs}
695 if [[ -z $(egetent group "${g}") ]] ; then
696 eerror "You must add group ${g} to the system first"
697 die "${g} is not a valid GID"
698 fi
699 if [[ -z ${defgroup} ]] ; then
700 defgroup=${g}
701 else
702 exgroups="${exgroups},${g}"
703 fi
704 export IFS=","
705 done
706 export IFS=${oldifs}
707
708 opts="${opts} -g ${defgroup}"
709 if [[ ! -z ${exgroups} ]] ; then
710 opts="${opts} -G ${exgroups:1}"
711 fi
712 else
713 egroups="(none)"
714 fi
715 einfo " - Groups: ${egroups}"
716
717 # handle extra and add the user
718 local oldsandbox=${SANDBOX_ON}
719 export SANDBOX_ON="0"
720 case ${CHOST} in
721 *-darwin*)
722 ### Make the user
723 if [[ -z $@ ]] ; then
724 dscl . create /users/${euser} uid ${euid}
725 dscl . create /users/${euser} shell ${eshell}
726 dscl . create /users/${euser} home ${ehome}
727 dscl . create /users/${euser} realname "added by portage for ${PN}"
728 ### Add the user to the groups specified
729 local oldifs=${IFS}
730 export IFS=","
731 for g in ${egroups} ; do
732 dscl . merge /groups/${g} users ${euser}
733 done
734 export IFS=${oldifs}
735 else
736 einfo "Extra options are not supported on Darwin yet"
737 einfo "Please report the ebuild along with the info below"
738 einfo "eextra: $@"
739 die "Required function missing"
740 fi
741 ;;
742 *-freebsd*|*-dragonfly*)
743 if [[ -z $@ ]] ; then
744 pw useradd ${euser} ${opts} \
745 -c "added by portage for ${PN}" \
746 die "enewuser failed"
747 else
748 einfo " - Extra: $@"
749 pw useradd ${euser} ${opts} \
750 "$@" || die "enewuser failed"
751 fi
752 ;;
753
754 *-netbsd*)
755 if [[ -z $@ ]] ; then
756 useradd ${opts} ${euser} || die "enewuser failed"
757 else
758 einfo " - Extra: $@"
759 useradd ${opts} ${euser} "$@" || die "enewuser failed"
760 fi
761 ;;
762
763 *-openbsd*)
764 if [[ -z $@ ]] ; then
765 useradd -u ${euid} -s ${eshell} \
766 -d ${ehome} -c "Added by portage for ${PN}" \
767 -g ${egroups} ${euser} || die "enewuser failed"
768 else
769 einfo " - Extra: $@"
770 useradd -u ${euid} -s ${eshell} \
771 -d ${ehome} -c "Added by portage for ${PN}" \
772 -g ${egroups} ${euser} "$@" || die "enewuser failed"
773 fi
774 ;;
775
776 *)
777 if [[ -z $@ ]] ; then
778 useradd -r ${opts} \
779 -c "added by portage for ${PN}" \
780 ${euser} \
781 || die "enewuser failed"
782 else
783 einfo " - Extra: $@"
784 useradd -r ${opts} "$@" \
785 ${euser} \
786 || die "enewuser failed"
787 fi
788 ;;
789 esac
790
791 if [[ ! -e ${ROOT}/${ehome} ]] ; then
792 einfo " - Creating ${ehome} in ${ROOT}"
793 mkdir -p "${ROOT}/${ehome}"
794 chown ${euser} "${ROOT}/${ehome}"
795 chmod 755 "${ROOT}/${ehome}"
796 fi
797
798 export SANDBOX_ON=${oldsandbox}
799}
800
801# @FUNCTION: enewgroup
802# @USAGE: <group> [gid]
803# @DESCRIPTION:
804# This function does not require you to understand how to properly add a
805# group to the system. Just give it a group name to add and enewgroup will
806# do the rest. You may specify the gid for the group or allow the group to
807# allocate the next available one.
808enewgroup() {
809 case ${EBUILD_PHASE} in
810 unpack|compile|test|install)
811 eerror "'enewgroup()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
812 eerror "Package fails at QA and at life. Please file a bug."
813 die "Bad package! enewgroup is only for use in pkg_* functions!"
814 esac
815
816 # get the group
817 local egroup="$1"; shift
818 if [ -z "${egroup}" ]
819 then
820 eerror "No group specified !"
821 die "Cannot call enewgroup without a group"
822 fi
823
824 # see if group already exists
825 if [[ -n $(egetent group "${egroup}") ]]; then
826 return 0
827 fi
828 einfo "Adding group '${egroup}' to your system ..."
829
830 # options to pass to useradd
831 local opts=
832
833 # handle gid
834 local egid="$1"; shift
835 if [ ! -z "${egid}" ]
836 then
837 if [ "${egid}" -gt 0 ]
838 then
839 if [ -z "`egetent group ${egid}`" ]
840 then
841 if [[ "${CHOST}" == *-darwin* ]]; then
842 opts="${opts} ${egid}"
843 else
844 opts="${opts} -g ${egid}"
845 fi
846 else
847 egid="next available; requested gid taken"
848 fi
849 else
850 eerror "Groupid given but is not greater than 0 !"
851 die "${egid} is not a valid GID"
852 fi
853 else
854 egid="next available"
855 fi
856 einfo " - Groupid: ${egid}"
857
858 # handle extra
859 local eextra="$@"
860 opts="${opts} ${eextra}"
861
862 # add the group
863 local oldsandbox="${SANDBOX_ON}"
864 export SANDBOX_ON="0"
865 case ${CHOST} in
866 *-darwin*)
867 if [ ! -z "${eextra}" ];
868 then
869 einfo "Extra options are not supported on Darwin/OS X yet"
870 einfo "Please report the ebuild along with the info below"
871 einfo "eextra: ${eextra}"
872 die "Required function missing"
873 fi
874
875 # If we need the next available
876 case ${egid} in
877 *[!0-9]*) # Non numeric
878 for ((egid = 101; egid <= 999; egid++)); do
879 [[ -z $(egetent group ${egid}) ]] && break
880 done
881 esac
882 dscl . create /groups/${egroup} gid ${egid}
883 dscl . create /groups/${egroup} passwd '*'
884 ;;
885
886 *-freebsd*|*-dragonfly*)
887 case ${egid} in
888 *[!0-9]*) # Non numeric
889 for ((egid = 101; egid <= 999; egid++)); do
890 [[ -z $(egetent group ${egid}) ]] && break
891 done
892 esac
893 pw groupadd ${egroup} -g ${egid} || die "enewgroup failed"
894 ;;
895
896 *-netbsd*)
897 case ${egid} in
898 *[!0-9]*) # Non numeric
899 for ((egid = 101; egid <= 999; egid++)); do
900 [[ -z $(egetent group ${egid}) ]] && break
901 done
902 esac
903 groupadd -g ${egid} ${egroup} || die "enewgroup failed"
904 ;;
905
906 *)
907 # We specify -r so that we get a GID in the system range from login.defs
908 groupadd -r ${opts} ${egroup} || die "enewgroup failed"
909 ;;
910 esac
911 export SANDBOX_ON="${oldsandbox}"
912}
913
914# @FUNCTION: edos2unix 613# @FUNCTION: edos2unix
915# @USAGE: <file> [more files ...] 614# @USAGE: <file> [more files ...]
916# @DESCRIPTION: 615# @DESCRIPTION:
917# A handy replacement for dos2unix, recode, fixdos, etc... This allows you 616# A handy replacement for dos2unix, recode, fixdos, etc... This allows you
918# to remove all of these text utilities from DEPEND variables because this 617# to remove all of these text utilities from DEPEND variables because this
919# is a script based solution. Just give it a list of files to convert and 618# is a script based solution. Just give it a list of files to convert and
920# they will all be changed from the DOS CRLF format to the UNIX LF format. 619# they will all be changed from the DOS CRLF format to the UNIX LF format.
921edos2unix() { 620edos2unix() {
922 echo "$@" | xargs sed -i 's/\r$//' 621 [[ $# -eq 0 ]] && return 0
622 sed -i 's/\r$//' -- "$@" || die
923} 623}
924 624
925# Make a desktop file ! 625# @FUNCTION: make_desktop_entry
926# Great for making those icons in kde/gnome startmenu !
927# Amaze your friends ! Get the women ! Join today !
928#
929# make_desktop_entry(<command>, [name], [icon], [type], [fields]) 626# @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
627# @DESCRIPTION:
628# Make a .desktop file.
930# 629#
630# @CODE
931# binary: what command does the app run with ? 631# binary: what command does the app run with ?
932# name: the name that will show up in the menu 632# name: the name that will show up in the menu
933# icon: give your little like a pretty little icon ... 633# icon: give your little like a pretty little icon ...
934# this can be relative (to /usr/share/pixmaps) or 634# this can be relative (to /usr/share/pixmaps) or
935# a full path to an icon 635# a full path to an icon
936# type: what kind of application is this ? for categories: 636# type: what kind of application is this?
637# for categories:
937# http://standards.freedesktop.org/menu-spec/latest/apa.html 638# http://standards.freedesktop.org/menu-spec/latest/apa.html
639# if unset, function tries to guess from package's category
938# fields: extra fields to append to the desktop file; a printf string 640# fields: extra fields to append to the desktop file; a printf string
641# @CODE
939make_desktop_entry() { 642make_desktop_entry() {
940 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable" 643 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
941 644
942 local exec=${1} 645 local exec=${1}
943 local name=${2:-${PN}} 646 local name=${2:-${PN}}
949 local catmaj=${CATEGORY%%-*} 652 local catmaj=${CATEGORY%%-*}
950 local catmin=${CATEGORY##*-} 653 local catmin=${CATEGORY##*-}
951 case ${catmaj} in 654 case ${catmaj} in
952 app) 655 app)
953 case ${catmin} in 656 case ${catmin} in
954 accessibility) type=Accessibility;; 657 accessibility) type="Utility;Accessibility";;
955 admin) type=System;; 658 admin) type=System;;
956 antivirus) type=System;; 659 antivirus) type=System;;
957 arch) type=Archiving;; 660 arch) type="Utility;Archiving";;
958 backup) type=Archiving;; 661 backup) type="Utility;Archiving";;
959 cdr) type=DiscBurning;; 662 cdr) type="AudioVideo;DiscBurning";;
960 dicts) type=Dictionary;; 663 dicts) type="Office;Dictionary";;
961 doc) type=Documentation;; 664 doc) type=Documentation;;
962 editors) type=TextEditor;; 665 editors) type="Utility;TextEditor";;
963 emacs) type=TextEditor;; 666 emacs) type="Development;TextEditor";;
964 emulation) type=Emulator;; 667 emulation) type="System;Emulator";;
965 laptop) type=HardwareSettings;; 668 laptop) type="Settings;HardwareSettings";;
966 office) type=Office;; 669 office) type=Office;;
967 pda) type=PDA;; 670 pda) type="Office;PDA";;
968 vim) type=TextEditor;; 671 vim) type="Development;TextEditor";;
969 xemacs) type=TextEditor;; 672 xemacs) type="Development;TextEditor";;
970 esac 673 esac
971 ;; 674 ;;
972 675
973 dev) 676 dev)
974 type="Development" 677 type="Development"
1250 # wrap the env here so that the 'insinto' call 953 # wrap the env here so that the 'insinto' call
1251 # doesn't corrupt the env of the caller 954 # doesn't corrupt the env of the caller
1252 insinto /usr/share/pixmaps 955 insinto /usr/share/pixmaps
1253 newins "$@" 956 newins "$@"
1254 ) 957 )
1255}
1256
1257# for internal use only (unpack_pdv and unpack_makeself)
1258find_unpackable_file() {
1259 local src=$1
1260 if [[ -z ${src} ]] ; then
1261 src=${DISTDIR}/${A}
1262 else
1263 if [[ -e ${DISTDIR}/${src} ]] ; then
1264 src=${DISTDIR}/${src}
1265 elif [[ -e ${PWD}/${src} ]] ; then
1266 src=${PWD}/${src}
1267 elif [[ -e ${src} ]] ; then
1268 src=${src}
1269 fi
1270 fi
1271 [[ ! -e ${src} ]] && return 1
1272 echo "${src}"
1273}
1274
1275# @FUNCTION: unpack_pdv
1276# @USAGE: <file to unpack> <size of off_t>
1277# @DESCRIPTION:
1278# Unpack those pesky pdv generated files ...
1279# They're self-unpacking programs with the binary package stuffed in
1280# the middle of the archive. Valve seems to use it a lot ... too bad
1281# it seems to like to segfault a lot :(. So lets take it apart ourselves.
1282#
1283# You have to specify the off_t size ... I have no idea how to extract that
1284# information out of the binary executable myself. Basically you pass in
1285# the size of the off_t type (in bytes) on the machine that built the pdv
1286# archive.
1287#
1288# One way to determine this is by running the following commands:
1289#
1290# @CODE
1291# strings <pdv archive> | grep lseek
1292# strace -elseek <pdv archive>
1293# @CODE
1294#
1295# Basically look for the first lseek command (we do the strings/grep because
1296# sometimes the function call is _llseek or something) and steal the 2nd
1297# parameter. Here is an example:
1298#
1299# @CODE
1300# vapier@vapier 0 pdv_unpack # strings hldsupdatetool.bin | grep lseek
1301# lseek
1302# vapier@vapier 0 pdv_unpack # strace -elseek ./hldsupdatetool.bin
1303# lseek(3, -4, SEEK_END) = 2981250
1304# @CODE
1305#
1306# Thus we would pass in the value of '4' as the second parameter.
1307unpack_pdv() {
1308 local src=$(find_unpackable_file "$1")
1309 local sizeoff_t=$2
1310
1311 [[ -z ${src} ]] && die "Could not locate source for '$1'"
1312 [[ -z ${sizeoff_t} ]] && die "No idea what off_t size was used for this pdv :("
1313
1314 local shrtsrc=$(basename "${src}")
1315 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1316 local metaskip=$(tail -c ${sizeoff_t} "${src}" | hexdump -e \"%i\")
1317 local tailskip=$(tail -c $((${sizeoff_t}*2)) "${src}" | head -c ${sizeoff_t} | hexdump -e \"%i\")
1318
1319 # grab metadata for debug reasons
1320 local metafile=$(emktemp)
1321 tail -c +$((${metaskip}+1)) "${src}" > "${metafile}"
1322
1323 # rip out the final file name from the metadata
1324 local datafile=$(tail -c +$((${metaskip}+1)) "${src}" | strings | head -n 1)
1325 datafile=$(basename "${datafile}")
1326
1327 # now lets uncompress/untar the file if need be
1328 local tmpfile=$(emktemp)
1329 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null | head -c 512 > ${tmpfile}
1330
1331 local iscompressed=$(file -b "${tmpfile}")
1332 if [[ ${iscompressed:0:8} == "compress" ]] ; then
1333 iscompressed=1
1334 mv ${tmpfile}{,.Z}
1335 gunzip ${tmpfile}
1336 else
1337 iscompressed=0
1338 fi
1339 local istar=$(file -b "${tmpfile}")
1340 if [[ ${istar:0:9} == "POSIX tar" ]] ; then
1341 istar=1
1342 else
1343 istar=0
1344 fi
1345
1346 #for some reason gzip dies with this ... dd cant provide buffer fast enough ?
1347 #dd if=${src} ibs=${metaskip} count=1 \
1348 # | dd ibs=${tailskip} skip=1 \
1349 # | gzip -dc \
1350 # > ${datafile}
1351 if [ ${iscompressed} -eq 1 ] ; then
1352 if [ ${istar} -eq 1 ] ; then
1353 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1354 | head -c $((${metaskip}-${tailskip})) \
1355 | tar -xzf -
1356 else
1357 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1358 | head -c $((${metaskip}-${tailskip})) \
1359 | gzip -dc \
1360 > ${datafile}
1361 fi
1362 else
1363 if [ ${istar} -eq 1 ] ; then
1364 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1365 | head -c $((${metaskip}-${tailskip})) \
1366 | tar --no-same-owner -xf -
1367 else
1368 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1369 | head -c $((${metaskip}-${tailskip})) \
1370 > ${datafile}
1371 fi
1372 fi
1373 true
1374 #[ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1375 #assert "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1376}
1377
1378# @FUNCTION: unpack_makeself
1379# @USAGE: [file to unpack] [offset] [tail|dd]
1380# @DESCRIPTION:
1381# Unpack those pesky makeself generated files ...
1382# They're shell scripts with the binary package tagged onto
1383# the end of the archive. Loki utilized the format as does
1384# many other game companies.
1385#
1386# If the file is not specified, then ${A} is used. If the
1387# offset is not specified then we will attempt to extract
1388# the proper offset from the script itself.
1389unpack_makeself() {
1390 local src_input=${1:-${A}}
1391 local src=$(find_unpackable_file "${src_input}")
1392 local skip=$2
1393 local exe=$3
1394
1395 [[ -z ${src} ]] && die "Could not locate source for '${src_input}'"
1396
1397 local shrtsrc=$(basename "${src}")
1398 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1399 if [[ -z ${skip} ]] ; then
1400 local ver=$(grep -m1 -a '#.*Makeself' "${src}" | awk '{print $NF}')
1401 local skip=0
1402 exe=tail
1403 case ${ver} in
1404 1.5.*|1.6.0-nv) # tested 1.5.{3,4,5} ... guessing 1.5.x series is same
1405 skip=$(grep -a ^skip= "${src}" | cut -d= -f2)
1406 ;;
1407 2.0|2.0.1)
1408 skip=$(grep -a ^$'\t'tail "${src}" | awk '{print $2}' | cut -b2-)
1409 ;;
1410 2.1.1)
1411 skip=$(grep -a ^offset= "${src}" | awk '{print $2}' | cut -b2-)
1412 (( skip++ ))
1413 ;;
1414 2.1.2)
1415 skip=$(grep -a ^offset= "${src}" | awk '{print $3}' | head -n 1)
1416 (( skip++ ))
1417 ;;
1418 2.1.3)
1419 skip=`grep -a ^offset= "${src}" | awk '{print $3}'`
1420 (( skip++ ))
1421 ;;
1422 2.1.4|2.1.5)
1423 skip=$(grep -a offset=.*head.*wc "${src}" | awk '{print $3}' | head -n 1)
1424 skip=$(head -n ${skip} "${src}" | wc -c)
1425 exe="dd"
1426 ;;
1427 *)
1428 eerror "I'm sorry, but I was unable to support the Makeself file."
1429 eerror "The version I detected was '${ver}'."
1430 eerror "Please file a bug about the file ${shrtsrc} at"
1431 eerror "http://bugs.gentoo.org/ so that support can be added."
1432 die "makeself version '${ver}' not supported"
1433 ;;
1434 esac
1435 debug-print "Detected Makeself version ${ver} ... using ${skip} as offset"
1436 fi
1437 case ${exe} in
1438 tail) exe="tail -n +${skip} '${src}'";;
1439 dd) exe="dd ibs=${skip} skip=1 if='${src}'";;
1440 *) die "makeself cant handle exe '${exe}'"
1441 esac
1442
1443 # lets grab the first few bytes of the file to figure out what kind of archive it is
1444 local filetype tmpfile=$(emktemp)
1445 eval ${exe} 2>/dev/null | head -c 512 > "${tmpfile}"
1446 filetype=$(file -b "${tmpfile}") || die
1447 case ${filetype} in
1448 *tar\ archive*)
1449 eval ${exe} | tar --no-same-owner -xf -
1450 ;;
1451 bzip2*)
1452 eval ${exe} | bzip2 -dc | tar --no-same-owner -xf -
1453 ;;
1454 gzip*)
1455 eval ${exe} | tar --no-same-owner -xzf -
1456 ;;
1457 compress*)
1458 eval ${exe} | gunzip | tar --no-same-owner -xf -
1459 ;;
1460 *)
1461 eerror "Unknown filetype \"${filetype}\" ?"
1462 false
1463 ;;
1464 esac
1465 assert "failure unpacking (${filetype}) makeself ${shrtsrc} ('${ver}' +${skip})"
1466}
1467
1468# @FUNCTION: check_license
1469# @USAGE: [license]
1470# @DESCRIPTION:
1471# Display a license for user to accept. If no license is
1472# specified, then ${LICENSE} is used.
1473check_license() {
1474 local lic=$1
1475 if [ -z "${lic}" ] ; then
1476 lic="${PORTDIR}/licenses/${LICENSE}"
1477 else
1478 if [ -e "${PORTDIR}/licenses/${lic}" ] ; then
1479 lic="${PORTDIR}/licenses/${lic}"
1480 elif [ -e "${PWD}/${lic}" ] ; then
1481 lic="${PWD}/${lic}"
1482 elif [ -e "${lic}" ] ; then
1483 lic="${lic}"
1484 fi
1485 fi
1486 local l="`basename ${lic}`"
1487
1488 # here is where we check for the licenses the user already
1489 # accepted ... if we don't find a match, we make the user accept
1490 local alic
1491 eshopts_push -o noglob # so that bash doesn't expand "*"
1492 for alic in ${ACCEPT_LICENSE} ; do
1493 if [[ ${alic} == ${l} ]]; then
1494 eshopts_pop
1495 return 0
1496 fi
1497 done
1498 eshopts_pop
1499 [ ! -f "${lic}" ] && die "Could not find requested license ${lic}"
1500
1501 local licmsg=$(emktemp)
1502 cat <<-EOF > ${licmsg}
1503 **********************************************************
1504 The following license outlines the terms of use of this
1505 package. You MUST accept this license for installation to
1506 continue. When you are done viewing, hit 'q'. If you
1507 CTRL+C out of this, the install will not run!
1508 **********************************************************
1509
1510 EOF
1511 cat ${lic} >> ${licmsg}
1512 ${PAGER:-less} ${licmsg} || die "Could not execute pager (${PAGER}) to accept ${lic}"
1513 einfon "Do you accept the terms of this license (${l})? [yes/no] "
1514 read alic
1515 case ${alic} in
1516 yes|Yes|y|Y)
1517 return 0
1518 ;;
1519 *)
1520 echo;echo;echo
1521 eerror "You MUST accept the license to continue! Exiting!"
1522 die "Failed to accept license"
1523 ;;
1524 esac
1525}
1526
1527# @FUNCTION: cdrom_get_cds
1528# @USAGE: <file on cd1> [file on cd2] [file on cd3] [...]
1529# @DESCRIPTION:
1530# Aquire cd(s) for those lovely cd-based emerges. Yes, this violates
1531# the whole 'non-interactive' policy, but damnit I want CD support !
1532#
1533# With these cdrom functions we handle all the user interaction and
1534# standardize everything. All you have to do is call cdrom_get_cds()
1535# and when the function returns, you can assume that the cd has been
1536# found at CDROM_ROOT.
1537#
1538# The function will attempt to locate a cd based upon a file that is on
1539# the cd. The more files you give this function, the more cds
1540# the cdrom functions will handle.
1541#
1542# Normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2',
1543# etc... If you want to give the cds better names, then just export
1544# the appropriate CDROM_NAME variable before calling cdrom_get_cds().
1545# Use CDROM_NAME for one cd, or CDROM_NAME_# for multiple cds. You can
1546# also use the CDROM_NAME_SET bash array.
1547#
1548# For those multi cd ebuilds, see the cdrom_load_next_cd() function.
1549cdrom_get_cds() {
1550 # first we figure out how many cds we're dealing with by
1551 # the # of files they gave us
1552 local cdcnt=0
1553 local f=
1554 for f in "$@" ; do
1555 ((++cdcnt))
1556 export CDROM_CHECK_${cdcnt}="$f"
1557 done
1558 export CDROM_TOTAL_CDS=${cdcnt}
1559 export CDROM_CURRENT_CD=1
1560
1561 # now we see if the user gave use CD_ROOT ...
1562 # if they did, let's just believe them that it's correct
1563 if [[ -n ${CD_ROOT}${CD_ROOT_1} ]] ; then
1564 local var=
1565 cdcnt=0
1566 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1567 ((++cdcnt))
1568 var="CD_ROOT_${cdcnt}"
1569 [[ -z ${!var} ]] && var="CD_ROOT"
1570 if [[ -z ${!var} ]] ; then
1571 eerror "You must either use just the CD_ROOT"
1572 eerror "or specify ALL the CD_ROOT_X variables."
1573 eerror "In this case, you will need ${CDROM_TOTAL_CDS} CD_ROOT_X variables."
1574 die "could not locate CD_ROOT_${cdcnt}"
1575 fi
1576 done
1577 export CDROM_ROOT=${CD_ROOT_1:-${CD_ROOT}}
1578 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1579 export CDROM_SET=-1
1580 for f in ${CDROM_CHECK_1//:/ } ; do
1581 ((++CDROM_SET))
1582 [[ -e ${CDROM_ROOT}/${f} ]] && break
1583 done
1584 export CDROM_MATCH=${f}
1585 return
1586 fi
1587
1588 # User didn't help us out so lets make sure they know they can
1589 # simplify the whole process ...
1590 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1591 einfo "This ebuild will need the ${CDROM_NAME:-cdrom for ${PN}}"
1592 echo
1593 einfo "If you do not have the CD, but have the data files"
1594 einfo "mounted somewhere on your filesystem, just export"
1595 einfo "the variable CD_ROOT so that it points to the"
1596 einfo "directory containing the files."
1597 echo
1598 einfo "For example:"
1599 einfo "export CD_ROOT=/mnt/cdrom"
1600 echo
1601 else
1602 if [[ -n ${CDROM_NAME_SET} ]] ; then
1603 # Translate the CDROM_NAME_SET array into CDROM_NAME_#
1604 cdcnt=0
1605 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1606 ((++cdcnt))
1607 export CDROM_NAME_${cdcnt}="${CDROM_NAME_SET[$((${cdcnt}-1))]}"
1608 done
1609 fi
1610
1611 einfo "This package will need access to ${CDROM_TOTAL_CDS} cds."
1612 cdcnt=0
1613 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1614 ((++cdcnt))
1615 var="CDROM_NAME_${cdcnt}"
1616 [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}"
1617 done
1618 echo
1619 einfo "If you do not have the CDs, but have the data files"
1620 einfo "mounted somewhere on your filesystem, just export"
1621 einfo "the following variables so they point to the right place:"
1622 einfon ""
1623 cdcnt=0
1624 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1625 ((++cdcnt))
1626 echo -n " CD_ROOT_${cdcnt}"
1627 done
1628 echo
1629 einfo "Or, if you have all the files in the same place, or"
1630 einfo "you only have one cdrom, you can export CD_ROOT"
1631 einfo "and that place will be used as the same data source"
1632 einfo "for all the CDs."
1633 echo
1634 einfo "For example:"
1635 einfo "export CD_ROOT_1=/mnt/cdrom"
1636 echo
1637 fi
1638
1639 export CDROM_SET=""
1640 export CDROM_CURRENT_CD=0
1641 cdrom_load_next_cd
1642}
1643
1644# @FUNCTION: cdrom_load_next_cd
1645# @DESCRIPTION:
1646# Some packages are so big they come on multiple CDs. When you're done reading
1647# files off a CD and want access to the next one, just call this function.
1648# Again, all the messy details of user interaction are taken care of for you.
1649# Once this returns, just read the variable CDROM_ROOT for the location of the
1650# mounted CD. Note that you can only go forward in the CD list, so make sure
1651# you only call this function when you're done using the current CD.
1652cdrom_load_next_cd() {
1653 local var
1654 ((++CDROM_CURRENT_CD))
1655
1656 unset CDROM_ROOT
1657 var=CD_ROOT_${CDROM_CURRENT_CD}
1658 [[ -z ${!var} ]] && var="CD_ROOT"
1659 if [[ -z ${!var} ]] ; then
1660 var="CDROM_CHECK_${CDROM_CURRENT_CD}"
1661 _cdrom_locate_file_on_cd ${!var}
1662 else
1663 export CDROM_ROOT=${!var}
1664 fi
1665
1666 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1667}
1668
1669# this is used internally by the cdrom_get_cds() and cdrom_load_next_cd()
1670# functions. this should *never* be called from an ebuild.
1671# all it does is try to locate a give file on a cd ... if the cd isn't
1672# found, then a message asking for the user to insert the cdrom will be
1673# displayed and we'll hang out here until:
1674# (1) the file is found on a mounted cdrom
1675# (2) the user hits CTRL+C
1676_cdrom_locate_file_on_cd() {
1677 local mline=""
1678 local showedmsg=0 showjolietmsg=0
1679
1680 while [[ -z ${CDROM_ROOT} ]] ; do
1681 local i=0
1682 local -a cdset=(${*//:/ })
1683 if [[ -n ${CDROM_SET} ]] ; then
1684 cdset=(${cdset[${CDROM_SET}]})
1685 fi
1686
1687 while [[ -n ${cdset[${i}]} ]] ; do
1688 local dir=$(dirname ${cdset[${i}]})
1689 local file=$(basename ${cdset[${i}]})
1690
1691 local point= node= fs= foo=
1692 while read point node fs foo ; do
1693 [[ " cd9660 iso9660 udf " != *" ${fs} "* ]] && \
1694 ! [[ ${fs} == "subfs" && ",${opts}," == *",fs=cdfss,"* ]] \
1695 && continue
1696 point=${point//\040/ }
1697 [[ ! -d ${point}/${dir} ]] && continue
1698 [[ -z $(find "${point}/${dir}" -maxdepth 1 -iname "${file}") ]] && continue
1699 export CDROM_ROOT=${point}
1700 export CDROM_SET=${i}
1701 export CDROM_MATCH=${cdset[${i}]}
1702 return
1703 done <<< "$(get_mounts)"
1704
1705 ((++i))
1706 done
1707
1708 echo
1709 if [[ ${showedmsg} -eq 0 ]] ; then
1710 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1711 if [[ -z ${CDROM_NAME} ]] ; then
1712 einfo "Please insert+mount the cdrom for ${PN} now !"
1713 else
1714 einfo "Please insert+mount the ${CDROM_NAME} cdrom now !"
1715 fi
1716 else
1717 if [[ -z ${CDROM_NAME_1} ]] ; then
1718 einfo "Please insert+mount cd #${CDROM_CURRENT_CD} for ${PN} now !"
1719 else
1720 local var="CDROM_NAME_${CDROM_CURRENT_CD}"
1721 einfo "Please insert+mount the ${!var} cdrom now !"
1722 fi
1723 fi
1724 showedmsg=1
1725 fi
1726 einfo "Press return to scan for the cd again"
1727 einfo "or hit CTRL+C to abort the emerge."
1728 echo
1729 if [[ ${showjolietmsg} -eq 0 ]] ; then
1730 showjolietmsg=1
1731 else
1732 ewarn "If you are having trouble with the detection"
1733 ewarn "of your CD, it is possible that you do not have"
1734 ewarn "Joliet support enabled in your kernel. Please"
1735 ewarn "check that CONFIG_JOLIET is enabled in your kernel."
1736 ebeep 5
1737 fi
1738 read || die "something is screwed with your system"
1739 done
1740} 958}
1741 959
1742# @FUNCTION: strip-linguas 960# @FUNCTION: strip-linguas
1743# @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>] 961# @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1744# @DESCRIPTION: 962# @DESCRIPTION:
1782 else 1000 else
1783 nols="${nols} ${f}" 1001 nols="${nols} ${f}"
1784 fi 1002 fi
1785 done 1003 done
1786 [[ -n ${nols} ]] \ 1004 [[ -n ${nols} ]] \
1787 && ewarn "Sorry, but ${PN} does not support the LINGUAS:" ${nols} 1005 && einfo "Sorry, but ${PN} does not support the LINGUAS:" ${nols}
1788 export LINGUAS=${newls:1} 1006 export LINGUAS=${newls:1}
1789} 1007}
1790 1008
1791# @FUNCTION: preserve_old_lib 1009# @FUNCTION: preserve_old_lib
1792# @USAGE: <libs to preserve> [more libs] 1010# @USAGE: <libs to preserve> [more libs]
2026 case ${opt} in 1244 case ${opt} in
2027 -a) return $(( r != 0 )) ;; 1245 -a) return $(( r != 0 )) ;;
2028 -o) return $(( r == $# )) ;; 1246 -o) return $(( r == $# )) ;;
2029 esac 1247 esac
2030} 1248}
1249
1250# @FUNCTION: in_iuse
1251# @USAGE: <flag>
1252# @DESCRIPTION:
1253# Determines whether the given flag is in IUSE. Strips IUSE default prefixes
1254# as necessary.
1255#
1256# Note that this function should not be used in the global scope.
1257in_iuse() {
1258 debug-print-function ${FUNCNAME} "${@}"
1259 [[ ${#} -eq 1 ]] || die "Invalid args to ${FUNCNAME}()"
1260
1261 local flag=${1}
1262 local liuse=( ${IUSE} )
1263
1264 has "${flag}" "${liuse[@]#[+-]}"
1265}
1266
1267# @FUNCTION: use_if_iuse
1268# @USAGE: <flag>
1269# @DESCRIPTION:
1270# Return true if the given flag is in USE and IUSE.
1271#
1272# Note that this function should not be used in the global scope.
1273use_if_iuse() {
1274 in_iuse $1 || return 1
1275 use $1
1276}
1277
1278# @FUNCTION: usex
1279# @USAGE: <USE flag> [true output] [false output] [true suffix] [false suffix]
1280# @DESCRIPTION:
1281# If USE flag is set, echo [true output][true suffix] (defaults to "yes"),
1282# otherwise echo [false output][false suffix] (defaults to "no").
1283usex() { use "$1" && echo "${2-yes}$4" || echo "${3-no}$5" ; } #382963
1284
1285# @FUNCTION: makeopts_jobs
1286# @USAGE: [${MAKEOPTS}]
1287# @DESCRIPTION:
1288# Searches the arguments (defaults to ${MAKEOPTS}) and extracts the jobs number
1289# specified therein. i.e. if the user has MAKEOPTS=-j9, this will show "9".
1290# We can't return the number as bash normalizes it to [0, 255]. If the flags
1291# havn't specified a -j flag, then "1" is shown as that is the default `make`
1292# uses. Useful for running non-make tools in parallel too.
1293makeopts_jobs() {
1294 [[ $# -eq 0 ]] && set -- ${MAKEOPTS}
1295 local x jobs
1296 for x ; do [[ ${x} == -j* ]] && jobs=${x#-j} ; done
1297 echo ${jobs:-1}
1298}
1299
1300check_license() { die "you no longer need this as portage supports ACCEPT_LICENSE itself"; }
1301
1302fi

Legend:
Removed from v.1.363  
changed lines
  Added in v.1.389

  ViewVC Help
Powered by ViewVC 1.1.20