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

Contents of /eclass/eutils.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.362 - (hide annotations) (download)
Tue Aug 9 00:43:48 2011 UTC (2 years, 11 months ago) by vapier
Branch: MAIN
Changes since 1.361: +2 -2 lines
fix typo pointed out by Samuli

1 vapier 1.356 # Copyright 1999-2011 Gentoo Foundation
2 azarah 1.1 # Distributed under the terms of the GNU General Public License v2
3 vapier 1.362 # $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.361 2011/08/08 02:01:40 vapier Exp $
4 vapier 1.283
5     # @ECLASS: eutils.eclass
6     # @MAINTAINER:
7     # base-system@gentoo.org
8     # @BLURB: many extra (but common) functions that are used in ebuilds
9     # @DESCRIPTION:
10     # The eutils eclass contains a suite of functions that complement
11     # the ones that ebuild.sh already contain. The idea is that the functions
12     # are not required in all ebuilds but enough utilize them to have a common
13     # home rather than having multiple ebuilds implementing the same thing.
14 swegener 1.286 #
15 vapier 1.283 # Due to the nature of this eclass, some functions may have maintainers
16     # different from the overall eclass!
17 azarah 1.1
18 flameeyes 1.197 inherit multilib portability
19 azarah 1.1
20 vapier 1.22 DESCRIPTION="Based on the ${ECLASS} eclass"
21 azarah 1.1
22 betelgeuse 1.329 if has "${EAPI:-0}" 0 1 2; then
23    
24 vapier 1.283 # @FUNCTION: epause
25     # @USAGE: [seconds]
26     # @DESCRIPTION:
27     # Sleep for the specified number of seconds (default of 5 seconds). Useful when
28     # printing a message the user should probably be reading and often used in
29     # conjunction with the ebeep function. If the EPAUSE_IGNORE env var is set,
30 betelgeuse 1.329 # don't wait at all. Defined in EAPIs 0 1 and 2.
31 ciaranm 1.98 epause() {
32 vapier 1.245 [[ -z ${EPAUSE_IGNORE} ]] && sleep ${1:-5}
33 ciaranm 1.98 }
34    
35 vapier 1.283 # @FUNCTION: ebeep
36     # @USAGE: [number of beeps]
37     # @DESCRIPTION:
38     # Issue the specified number of beeps (default of 5 beeps). Useful when
39     # printing a message the user should probably be reading and often used in
40     # conjunction with the epause function. If the EBEEP_IGNORE env var is set,
41 betelgeuse 1.329 # don't beep at all. Defined in EAPIs 0 1 and 2.
42 ciaranm 1.98 ebeep() {
43     local n
44 vapier 1.245 if [[ -z ${EBEEP_IGNORE} ]] ; then
45 ciaranm 1.98 for ((n=1 ; n <= ${1:-5} ; n++)) ; do
46     echo -ne "\a"
47     sleep 0.1 &>/dev/null ; sleep 0,1 &>/dev/null
48     echo -ne "\a"
49     sleep 1
50     done
51     fi
52     }
53    
54 reavertm 1.331 else
55    
56 reavertm 1.332 ebeep() {
57 reavertm 1.337 ewarn "QA Notice: ebeep is not defined in EAPI=${EAPI}, please file a bug at http://bugs.gentoo.org"
58 reavertm 1.332 }
59 reavertm 1.331
60 reavertm 1.332 epause() {
61 reavertm 1.337 ewarn "QA Notice: epause is not defined in EAPI=${EAPI}, please file a bug at http://bugs.gentoo.org"
62 reavertm 1.332 }
63 reavertm 1.331
64 betelgeuse 1.329 fi
65    
66 betelgeuse 1.348 # @FUNCTION: eqawarn
67     # @USAGE: [message]
68     # @DESCRIPTION:
69     # Proxy to einfo for package managers that don't provide eqawarn and use the PM
70     # implementation if available.
71     if ! declare -F eqawarn >/dev/null ; then
72     eqawarn() {
73     einfo "$@"
74     }
75     fi
76    
77 hollow 1.298 # @FUNCTION: ecvs_clean
78 vapier 1.299 # @USAGE: [list of dirs]
79 hollow 1.298 # @DESCRIPTION:
80 vapier 1.299 # Remove CVS directories recursiveley. Useful when a source tarball contains
81     # internal CVS directories. Defaults to $PWD.
82 hollow 1.298 ecvs_clean() {
83 vapier 1.299 [[ -z $* ]] && set -- .
84 hollow 1.298 find "$@" -type d -name 'CVS' -prune -print0 | xargs -0 rm -rf
85     find "$@" -type f -name '.cvs*' -print0 | xargs -0 rm -rf
86     }
87    
88     # @FUNCTION: esvn_clean
89 vapier 1.299 # @USAGE: [list of dirs]
90 hollow 1.298 # @DESCRIPTION:
91 vapier 1.299 # Remove .svn directories recursiveley. Useful when a source tarball contains
92     # internal Subversion directories. Defaults to $PWD.
93 hollow 1.298 esvn_clean() {
94 vapier 1.299 [[ -z $* ]] && set -- .
95 hollow 1.298 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
96     }
97    
98 vapier 1.322 # @FUNCTION: eshopts_push
99 vapier 1.330 # @USAGE: [options to `set` or `shopt`]
100 vapier 1.322 # @DESCRIPTION:
101     # 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
103     # assume the default state), eshopts_push is used to (1) push the current shell
104     # options onto a stack and (2) pass the specified arguments to set.
105     #
106 vapier 1.330 # If the first argument is '-s' or '-u', we assume you want to call `shopt`
107     # rather than `set` as there are some options only available via that.
108     #
109 vapier 1.322 # 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:
111     # @CODE
112     # eshopts_push -o noglob
113     # for x in ${foo} ; do
114     # if ...some check... ; then
115     # eshopts_pop
116     # return 0
117     # fi
118     # done
119     # eshopts_pop
120     # @CODE
121     eshopts_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 vapier 1.330 if [[ $1 == -[su] ]] ; then
126     __ESHOPTS_SAVE__[$i]=$(shopt -p)
127     [[ $# -eq 0 ]] && return 0
128     shopt "$@" || die "eshopts_push: bad options to shopt: $*"
129     else
130     __ESHOPTS_SAVE__[$i]=$-
131     [[ $# -eq 0 ]] && return 0
132     set "$@" || die "eshopts_push: bad options to set: $*"
133     fi
134 vapier 1.322 }
135    
136     # @FUNCTION: eshopts_pop
137     # @USAGE:
138     # @DESCRIPTION:
139     # Restore the shell options to the state saved with the corresponding
140     # eshopts_push call. See that function for more details.
141     eshopts_pop() {
142     [[ $# -ne 0 ]] && die "eshopts_pop takes no arguments"
143     local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 ))
144     [[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
145     local s=${__ESHOPTS_SAVE__[$i]}
146     unset __ESHOPTS_SAVE__[$i]
147 vapier 1.330 if [[ ${s} == "shopt -"* ]] ; then
148     eval "${s}" || die "eshopts_pop: sanity: invalid shopt options: ${s}"
149     else
150     set +$- || die "eshopts_pop: sanity: invalid shell settings: $-"
151     set -${s} || die "eshopts_pop: sanity: unable to restore saved shell settings: ${s}"
152     fi
153 vapier 1.322 }
154    
155 vapier 1.325 # @VARIABLE: EPATCH_SOURCE
156     # @DESCRIPTION:
157     # Default directory to search for patches.
158 azarah 1.2 EPATCH_SOURCE="${WORKDIR}/patch"
159 vapier 1.325 # @VARIABLE: EPATCH_SUFFIX
160     # @DESCRIPTION:
161     # Default extension for patches (do not prefix the period yourself).
162 azarah 1.2 EPATCH_SUFFIX="patch.bz2"
163 vapier 1.325 # @VARIABLE: EPATCH_OPTS
164     # @DESCRIPTION:
165     # Default options for patch:
166     # @CODE
167     # -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
168     # --no-backup-if-mismatch - do not leave .orig files behind
169     # -E - automatically remove empty files
170     # @CODE
171 vapier 1.230 EPATCH_OPTS="-g0 -E --no-backup-if-mismatch"
172 vapier 1.325 # @VARIABLE: EPATCH_EXCLUDE
173     # @DESCRIPTION:
174 mr_bones_ 1.308 # List of patches not to apply. Note this is only file names,
175 vapier 1.325 # and not the full path. Globs accepted.
176 azarah 1.6 EPATCH_EXCLUDE=""
177 vapier 1.325 # @VARIABLE: EPATCH_SINGLE_MSG
178     # @DESCRIPTION:
179 azarah 1.9 # Change the printed message for a single patch.
180     EPATCH_SINGLE_MSG=""
181 vapier 1.325 # @VARIABLE: EPATCH_MULTI_MSG
182     # @DESCRIPTION:
183 vapier 1.173 # Change the printed message for multiple patches.
184     EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates) ..."
185 vapier 1.325 # @VARIABLE: EPATCH_FORCE
186     # @DESCRIPTION:
187     # Only require patches to match EPATCH_SUFFIX rather than the extended
188     # arch naming style.
189 azarah 1.29 EPATCH_FORCE="no"
190 azarah 1.2
191 vapier 1.325 # @FUNCTION: epatch
192     # @USAGE: [patches] [dirs of patches]
193     # @DESCRIPTION:
194     # epatch is designed to greatly simplify the application of patches. It can
195     # process patch files directly, or directories of patches. The patches may be
196     # compressed (bzip/gzip/etc...) or plain text. You generally need not specify
197     # the -p option as epatch will automatically attempt -p0 to -p5 until things
198     # apply successfully.
199 azarah 1.2 #
200 vapier 1.325 # If you do not specify any options, then epatch will default to the directory
201     # specified by EPATCH_SOURCE.
202 azarah 1.2 #
203 vapier 1.325 # When processing directories, epatch will apply all patches that match:
204     # @CODE
205 vapier 1.350 # if ${EPATCH_FORCE} != "yes"
206 vapier 1.325 # ??_${ARCH}_foo.${EPATCH_SUFFIX}
207     # else
208     # *.${EPATCH_SUFFIX}
209     # @CODE
210     # The leading ?? are typically numbers used to force consistent patch ordering.
211     # The arch field is used to apply patches only for the host architecture with
212     # the special value of "all" means apply for everyone. Note that using values
213     # other than "all" is highly discouraged -- you should apply patches all the
214     # time and let architecture details be detected at configure/compile time.
215 azarah 1.2 #
216 vapier 1.325 # If EPATCH_SUFFIX is empty, then no period before it is implied when searching
217     # for patches to apply.
218 azarah 1.2 #
219 vapier 1.325 # Refer to the other EPATCH_xxx variables for more customization of behavior.
220 azarah 1.2 epatch() {
221 swegener 1.231 _epatch_draw_line() {
222 vapier 1.325 # create a line of same length as input string
223 agriffis 1.229 [[ -z $1 ]] && set "$(printf "%65s" '')"
224     echo "${1//?/=}"
225 vapier 1.219 }
226 azarah 1.3
227 vapier 1.195 unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
228    
229 vapier 1.325 # Let the rest of the code process one user arg at a time --
230     # each arg may expand into multiple patches, and each arg may
231     # need to start off with the default global EPATCH_xxx values
232     if [[ $# -gt 1 ]] ; then
233     local m
234 vapier 1.94 for m in "$@" ; do
235     epatch "${m}"
236     done
237     return 0
238 azarah 1.3 fi
239    
240 vapier 1.325 local SINGLE_PATCH="no"
241     # no args means process ${EPATCH_SOURCE}
242     [[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}"
243    
244     if [[ -f $1 ]] ; then
245 azarah 1.3 SINGLE_PATCH="yes"
246 vapier 1.325 set -- "$1"
247     # Use the suffix from the single patch (localize it); the code
248     # below will find the suffix for us
249     local EPATCH_SUFFIX=$1
250    
251     elif [[ -d $1 ]] ; then
252     # Some people like to make dirs of patches w/out suffixes (vim)
253     set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
254 danarmak 1.32
255 vapier 1.359 elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
256     # Re-use EPATCH_SOURCE as a search dir
257     epatch "${EPATCH_SOURCE}/$1"
258     return $?
259    
260 azarah 1.3 else
261 vapier 1.325 # sanity check ... if it isn't a dir or file, wtf man ?
262     [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
263     echo
264     eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:"
265     eerror
266     eerror " ${EPATCH_SOURCE}"
267     eerror " ( ${EPATCH_SOURCE##*/} )"
268     echo
269     die "Cannot find \$EPATCH_SOURCE!"
270 azarah 1.3 fi
271 azarah 1.2
272 vapier 1.325 local PIPE_CMD
273 azarah 1.2 case ${EPATCH_SUFFIX##*\.} in
274 vapier 1.325 xz) PIPE_CMD="xz -dc" ;;
275     lzma) PIPE_CMD="lzma -dc" ;;
276     bz2) PIPE_CMD="bzip2 -dc" ;;
277     gz|Z|z) PIPE_CMD="gzip -dc" ;;
278     ZIP|zip) PIPE_CMD="unzip -p" ;;
279     *) ;;
280 azarah 1.2 esac
281    
282 vapier 1.325 [[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}"
283    
284     local x
285     for x in "$@" ; do
286     # If the patch dir given contains subdirs, or our EPATCH_SUFFIX
287     # didn't match anything, ignore continue on
288     [[ ! -f ${x} ]] && continue
289    
290     local patchname=${x##*/}
291    
292     # Apply single patches, or forced sets of patches, or
293     # patches with ARCH dependant names.
294 flameeyes 1.266 # ???_arch_foo.patch
295 vapier 1.325 # Else, skip this input altogether
296     local a=${patchname#*_} # strip the ???_
297     a=${a%%_*} # strip the _foo.patch
298     if ! [[ ${SINGLE_PATCH} == "yes" || \
299 ulm 1.354 ${EPATCH_FORCE} == "yes" || \
300     ${a} == all || \
301     ${a} == ${ARCH} ]]
302 azarah 1.2 then
303 vapier 1.325 continue
304     fi
305 azarah 1.6
306 vapier 1.325 # Let people filter things dynamically
307     if [[ -n ${EPATCH_EXCLUDE} ]] ; then
308     # let people use globs in the exclude
309     eshopts_push -o noglob
310    
311 scarabeus 1.328 local ex
312 vapier 1.325 for ex in ${EPATCH_EXCLUDE} ; do
313 scarabeus 1.328 if [[ ${patchname} == ${ex} ]] ; then
314     eshopts_pop
315     continue 2
316     fi
317 vapier 1.325 done
318 vapier 1.326
319 vapier 1.325 eshopts_pop
320     fi
321 danarmak 1.32
322 vapier 1.325 if [[ ${SINGLE_PATCH} == "yes" ]] ; then
323     if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then
324     einfo "${EPATCH_SINGLE_MSG}"
325 azarah 1.3 else
326 vapier 1.325 einfo "Applying ${patchname} ..."
327 azarah 1.3 fi
328 vapier 1.325 else
329     einfo " ${patchname} ..."
330     fi
331 azarah 1.2
332 vapier 1.325 # most of the time, there will only be one run per unique name,
333     # but if there are more, make sure we get unique log filenames
334     local STDERR_TARGET="${T}/${patchname}.out"
335     if [[ -e ${STDERR_TARGET} ]] ; then
336     STDERR_TARGET="${T}/${patchname}-$$.out"
337     fi
338 azarah 1.2
339 vapier 1.325 printf "***** %s *****\n\n" "${patchname}" > "${STDERR_TARGET}"
340 vapier 1.304
341 vapier 1.325 # Decompress the patch if need be
342     local count=0
343     local PATCH_TARGET
344     if [[ -n ${PIPE_CMD} ]] ; then
345     PATCH_TARGET="${T}/$$.patch"
346     echo "PIPE_COMMAND: ${PIPE_CMD} ${x} > ${PATCH_TARGET}" >> "${STDERR_TARGET}"
347 vapier 1.304
348 vapier 1.325 if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then
349     echo
350     eerror "Could not extract patch!"
351     #die "Could not extract patch!"
352     count=5
353     break
354 vapier 1.305 fi
355 vapier 1.325 else
356     PATCH_TARGET=${x}
357     fi
358 vapier 1.305
359 vapier 1.325 # Check for absolute paths in patches. If sandbox is disabled,
360     # people could (accidently) patch files in the root filesystem.
361     # Or trigger other unpleasantries #237667. So disallow -p0 on
362     # such patches.
363     local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk '$2 != "/dev/null" { print }')
364     if [[ -n ${abs_paths} ]] ; then
365     count=1
366     printf "NOTE: skipping -p0 due to absolute paths in patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
367     fi
368 vapier 1.353 # Similar reason, but with relative paths.
369     local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' "${PATCH_TARGET}")
370     if [[ -n ${rel_paths} ]] ; then
371     eqawarn "QA Notice: Your patch uses relative paths '../'."
372     eqawarn " In the future this will cause a failure."
373     eqawarn "${rel_paths}"
374     fi
375 vapier 1.325
376     # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
377     while [[ ${count} -lt 5 ]] ; do
378     # Generate some useful debug info ...
379     (
380     _epatch_draw_line "***** ${patchname} *****"
381     echo
382     echo "PATCH COMMAND: patch -p${count} ${EPATCH_OPTS} < '${PATCH_TARGET}'"
383     echo
384     _epatch_draw_line "***** ${patchname} *****"
385 vapier 1.360 patch -p${count} ${EPATCH_OPTS} --dry-run -f < "${PATCH_TARGET}" 2>&1
386     ret=$?
387     echo
388     echo "patch program exited with status ${ret}"
389     exit ${ret}
390 vapier 1.325 ) >> "${STDERR_TARGET}"
391 azarah 1.8
392 vapier 1.360 if [ $? -eq 0 ] ; then
393 vapier 1.325 (
394     _epatch_draw_line "***** ${patchname} *****"
395     echo
396     echo "ACTUALLY APPLYING ${patchname} ..."
397     echo
398     _epatch_draw_line "***** ${patchname} *****"
399     patch -p${count} ${EPATCH_OPTS} < "${PATCH_TARGET}" 2>&1
400 vapier 1.360 ret=$?
401     echo
402     echo "patch program exited with status ${ret}"
403     exit ${ret}
404 vapier 1.325 ) >> "${STDERR_TARGET}"
405 danarmak 1.32
406 vapier 1.325 if [ $? -ne 0 ] ; then
407     echo
408     eerror "A dry-run of patch command succeeded, but actually"
409     eerror "applying the patch failed!"
410     #die "Real world sux compared to the dreamworld!"
411     count=5
412 azarah 1.2 fi
413 vapier 1.325 break
414 azarah 1.8 fi
415    
416 vapier 1.325 : $(( count++ ))
417     done
418 azarah 1.8
419 vapier 1.325 # if we had to decompress the patch, delete the temp one
420     if [[ -n ${PIPE_CMD} ]] ; then
421     rm -f "${PATCH_TARGET}"
422     fi
423 azarah 1.3
424 vapier 1.325 if [[ ${count} -ge 5 ]] ; then
425     echo
426     eerror "Failed Patch: ${patchname} !"
427     eerror " ( ${PATCH_TARGET} )"
428     eerror
429     eerror "Include in your bugreport the contents of:"
430     eerror
431     eerror " ${STDERR_TARGET}"
432     echo
433     die "Failed Patch: ${patchname}!"
434 azarah 1.2 fi
435 vapier 1.325
436     # if everything worked, delete the patch log
437     rm -f "${STDERR_TARGET}"
438     eend 0
439 azarah 1.2 done
440 vapier 1.325
441     [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
442     : # everything worked
443 azarah 1.26 }
444 vapier 1.361
445     # @FUNCTION: epatch_user
446     # @USAGE:
447     # @DESCRIPTION:
448     # Applies user-provided patches to the source tree. The patches are
449     # taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>/, where the first
450     # of these three directories to exist will be the one to use, ignoring
451     # any more general directories which might exist as well.
452     #
453     # User patches are intended for quick testing of patches without ebuild
454     # modifications, as well as for permanent customizations a user might
455     # desire. Obviously, there can be no official support for arbitrarily
456     # patched ebuilds. So whenever a build log in a bug report mentions that
457     # user patches were applied, the user should be asked to reproduce the
458     # problem without these.
459     #
460     # Not all ebuilds do call this function, so placing patches in the
461     # stated directory might or might not work, depending on the package and
462     # the eclasses it inherits and uses. It is safe to call the function
463     # repeatedly, so it is always possible to add a call at the ebuild
464     # level. The first call is the time when the patches will be
465     # applied.
466     #
467     # Ideally, this function should be called after gentoo-specific patches
468     # have been applied, so that their code can be modified as well, but
469     # before calls to e.g. eautoreconf, as the user patches might affect
470     # autotool input files as well.
471 vapier 1.318 epatch_user() {
472     [[ $# -ne 0 ]] && die "epatch_user takes no options"
473    
474 vapier 1.361 # Allow multiple calls to this function; ignore all but the first
475 vapier 1.362 local applied="${T}/epatch_user.applied"
476 vapier 1.361 [[ -e ${applied} ]] && return 2
477    
478 vapier 1.318 # don't clobber any EPATCH vars that the parent might want
479 zmedico 1.323 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
480 vapier 1.318 for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do
481     EPATCH_SOURCE=${base}/${CTARGET}/${check}
482     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
483     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
484     if [[ -d ${EPATCH_SOURCE} ]] ; then
485     EPATCH_SOURCE=${EPATCH_SOURCE} \
486     EPATCH_SUFFIX="patch" \
487     EPATCH_FORCE="yes" \
488     EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
489     epatch
490 vapier 1.361 echo "${EPATCH_SOURCE}" > "${applied}"
491 vapier 1.349 return 0
492 vapier 1.318 fi
493     done
494 vapier 1.361 echo "none" > "${applied}"
495 vapier 1.349 return 1
496 vapier 1.318 }
497 azarah 1.26
498 vapier 1.283 # @FUNCTION: emktemp
499     # @USAGE: [temp dir]
500     # @DESCRIPTION:
501 vapier 1.52 # Cheap replacement for when debianutils (and thus mktemp)
502 vapier 1.283 # does not exist on the users system.
503 vapier 1.117 emktemp() {
504 vapier 1.119 local exe="touch"
505 vapier 1.194 [[ $1 == -d ]] && exe="mkdir" && shift
506     local topdir=$1
507 mr_bones_ 1.100
508 vapier 1.194 if [[ -z ${topdir} ]] ; then
509     [[ -z ${T} ]] \
510 vapier 1.117 && topdir="/tmp" \
511 vapier 1.194 || topdir=${T}
512 vapier 1.117 fi
513    
514 vapier 1.280 if ! type -P mktemp > /dev/null ; then
515     # system lacks `mktemp` so we have to fake it
516 vapier 1.117 local tmp=/
517 vapier 1.194 while [[ -e ${tmp} ]] ; do
518     tmp=${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM}
519 vapier 1.117 done
520 vapier 1.194 ${exe} "${tmp}" || ${exe} -p "${tmp}"
521 vapier 1.117 echo "${tmp}"
522 vapier 1.52 else
523 vapier 1.280 # the args here will give slightly wierd names on BSD,
524     # but should produce a usable file on all userlands
525 flameeyes 1.223 if [[ ${exe} == "touch" ]] ; then
526 vapier 1.280 TMPDIR="${topdir}" mktemp -t tmp.XXXXXXXXXX
527 flameeyes 1.223 else
528 vapier 1.280 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
529 flameeyes 1.223 fi
530 vapier 1.52 fi
531     }
532    
533 vapier 1.283 # @FUNCTION: egetent
534     # @USAGE: <database> <key>
535     # @MAINTAINER:
536     # base-system@gentoo.org (Linux)
537     # Joe Jezak <josejx@gmail.com> (OS X)
538     # usata@gentoo.org (OS X)
539     # Aaron Walker <ka0ttic@gentoo.org> (FreeBSD)
540     # @DESCRIPTION:
541 grobian 1.310 # Small wrapper for getent (Linux),
542     # nidump (< Mac OS X 10.5), dscl (Mac OS X 10.5),
543 ka0ttic 1.108 # and pw (FreeBSD) used in enewuser()/enewgroup()
544 usata 1.91 egetent() {
545 flameeyes 1.205 case ${CHOST} in
546 grobian 1.319 *-darwin[678])
547 grobian 1.310 case "$2" in
548     *[!0-9]*) # Non numeric
549 betelgeuse 1.357 nidump $1 . | awk -F":" "{ if (\$1 ~ /^$2\$/) {print \$0;exit;} }"
550 grobian 1.310 ;;
551     *) # Numeric
552 grobian 1.319 nidump $1 . | awk -F":" "{ if (\$3 == $2) {print \$0;exit;} }"
553 grobian 1.310 ;;
554     esac
555     ;;
556 flameeyes 1.205 *-darwin*)
557 grobian 1.319 local mytype=$1
558     [[ "passwd" == $mytype ]] && mytype="Users"
559     [[ "group" == $mytype ]] && mytype="Groups"
560 usata 1.91 case "$2" in
561 flameeyes 1.205 *[!0-9]*) # Non numeric
562 grobian 1.319 dscl . -read /$mytype/$2 2>/dev/null |grep RecordName
563 usata 1.91 ;;
564 flameeyes 1.205 *) # Numeric
565 grobian 1.319 local mykey="UniqueID"
566     [[ $mytype == "Groups" ]] && mykey="PrimaryGroupID"
567     dscl . -search /$mytype $mykey $2 2>/dev/null
568 usata 1.91 ;;
569     esac
570 flameeyes 1.205 ;;
571 flameeyes 1.220 *-freebsd*|*-dragonfly*)
572 ka0ttic 1.203 local opts action="user"
573     [[ $1 == "passwd" ]] || action="group"
574    
575     # lookup by uid/gid
576     if [[ $2 == [[:digit:]]* ]] ; then
577     [[ ${action} == "user" ]] && opts="-u" || opts="-g"
578 ka0ttic 1.108 fi
579 ka0ttic 1.203
580     pw show ${action} ${opts} "$2" -q
581 flameeyes 1.205 ;;
582 flameeyes 1.218 *-netbsd*|*-openbsd*)
583 flameeyes 1.206 grep "$2:\*:" /etc/$1
584     ;;
585 flameeyes 1.205 *)
586     type -p nscd >& /dev/null && nscd -i "$1"
587 vapier 1.107 getent "$1" "$2"
588 flameeyes 1.205 ;;
589     esac
590 usata 1.91 }
591    
592 vapier 1.283 # @FUNCTION: enewuser
593     # @USAGE: <user> [uid] [shell] [homedir] [groups] [params]
594     # @DESCRIPTION:
595     # Same as enewgroup, you are not required to understand how to properly add
596     # a user to the system. The only required parameter is the username.
597     # Default uid is (pass -1 for this) next available, default shell is
598     # /bin/false, default homedir is /dev/null, there are no default groups,
599     # and default params sets the comment as 'added by portage for ${PN}'.
600 vapier 1.23 enewuser() {
601 vapier 1.233 case ${EBUILD_PHASE} in
602     unpack|compile|test|install)
603     eerror "'enewuser()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
604     eerror "Package fails at QA and at life. Please file a bug."
605     die "Bad package! enewuser is only for use in pkg_* functions!"
606     esac
607    
608 vapier 1.23 # get the username
609 vapier 1.182 local euser=$1; shift
610     if [[ -z ${euser} ]] ; then
611 vapier 1.23 eerror "No username specified !"
612     die "Cannot call enewuser without a username"
613     fi
614    
615 vapier 1.84 # lets see if the username already exists
616 agriffis 1.256 if [[ -n $(egetent passwd "${euser}") ]] ; then
617 vapier 1.23 return 0
618     fi
619 wolf31o2 1.44 einfo "Adding user '${euser}' to your system ..."
620 vapier 1.23
621     # options to pass to useradd
622 azarah 1.59 local opts=
623 vapier 1.23
624     # handle uid
625 vapier 1.182 local euid=$1; shift
626 agriffis 1.256 if [[ -n ${euid} && ${euid} != -1 ]] ; then
627 vapier 1.182 if [[ ${euid} -gt 0 ]] ; then
628 agriffis 1.256 if [[ -n $(egetent passwd ${euid}) ]] ; then
629 vapier 1.84 euid="next"
630 vapier 1.82 fi
631 vapier 1.23 else
632     eerror "Userid given but is not greater than 0 !"
633     die "${euid} is not a valid UID"
634     fi
635     else
636 vapier 1.84 euid="next"
637     fi
638 vapier 1.182 if [[ ${euid} == "next" ]] ; then
639 agriffis 1.256 for ((euid = 101; euid <= 999; euid++)); do
640 vapier 1.182 [[ -z $(egetent passwd ${euid}) ]] && break
641 vapier 1.84 done
642 vapier 1.23 fi
643 vapier 1.84 opts="${opts} -u ${euid}"
644 vapier 1.23 einfo " - Userid: ${euid}"
645    
646     # handle shell
647 vapier 1.182 local eshell=$1; shift
648     if [[ ! -z ${eshell} ]] && [[ ${eshell} != "-1" ]] ; then
649 vapier 1.221 if [[ ! -e ${ROOT}${eshell} ]] ; then
650 vapier 1.23 eerror "A shell was specified but it does not exist !"
651 vapier 1.221 die "${eshell} does not exist in ${ROOT}"
652     fi
653     if [[ ${eshell} == */false || ${eshell} == */nologin ]] ; then
654     eerror "Do not specify ${eshell} yourself, use -1"
655     die "Pass '-1' as the shell parameter"
656 vapier 1.23 fi
657     else
658 vapier 1.204 for shell in /sbin/nologin /usr/sbin/nologin /bin/false /usr/bin/false /dev/null ; do
659     [[ -x ${ROOT}${shell} ]] && break
660 flameeyes 1.198 done
661    
662 vapier 1.204 if [[ ${shell} == "/dev/null" ]] ; then
663 flameeyes 1.253 eerror "Unable to identify the shell to use, proceeding with userland default."
664     case ${USERLAND} in
665     GNU) shell="/bin/false" ;;
666     BSD) shell="/sbin/nologin" ;;
667     Darwin) shell="/usr/sbin/nologin" ;;
668     *) die "Unable to identify the default shell for userland ${USERLAND}"
669     esac
670 flameeyes 1.198 fi
671    
672     eshell=${shell}
673 vapier 1.23 fi
674     einfo " - Shell: ${eshell}"
675     opts="${opts} -s ${eshell}"
676    
677     # handle homedir
678 vapier 1.182 local ehome=$1; shift
679     if [[ -z ${ehome} ]] || [[ ${ehome} == "-1" ]] ; then
680 azarah 1.59 ehome="/dev/null"
681 vapier 1.23 fi
682     einfo " - Home: ${ehome}"
683     opts="${opts} -d ${ehome}"
684    
685     # handle groups
686 vapier 1.182 local egroups=$1; shift
687     if [[ ! -z ${egroups} ]] ; then
688     local oldifs=${IFS}
689 vapier 1.107 local defgroup="" exgroups=""
690    
691 vapier 1.23 export IFS=","
692 vapier 1.182 for g in ${egroups} ; do
693     export IFS=${oldifs}
694     if [[ -z $(egetent group "${g}") ]] ; then
695 vapier 1.85 eerror "You must add group ${g} to the system first"
696 vapier 1.23 die "${g} is not a valid GID"
697     fi
698 vapier 1.182 if [[ -z ${defgroup} ]] ; then
699     defgroup=${g}
700 vapier 1.107 else
701     exgroups="${exgroups},${g}"
702     fi
703 usata 1.115 export IFS=","
704 vapier 1.23 done
705 vapier 1.182 export IFS=${oldifs}
706 vapier 1.107
707     opts="${opts} -g ${defgroup}"
708 vapier 1.182 if [[ ! -z ${exgroups} ]] ; then
709 vapier 1.107 opts="${opts} -G ${exgroups:1}"
710     fi
711 vapier 1.23 else
712     egroups="(none)"
713     fi
714     einfo " - Groups: ${egroups}"
715    
716     # handle extra and add the user
717 vapier 1.182 local oldsandbox=${SANDBOX_ON}
718 vapier 1.23 export SANDBOX_ON="0"
719 flameeyes 1.205 case ${CHOST} in
720     *-darwin*)
721 usata 1.91 ### Make the user
722 vapier 1.182 if [[ -z $@ ]] ; then
723 usata 1.91 dscl . create /users/${euser} uid ${euid}
724     dscl . create /users/${euser} shell ${eshell}
725     dscl . create /users/${euser} home ${ehome}
726     dscl . create /users/${euser} realname "added by portage for ${PN}"
727     ### Add the user to the groups specified
728 vapier 1.182 local oldifs=${IFS}
729 usata 1.115 export IFS=","
730 vapier 1.182 for g in ${egroups} ; do
731 usata 1.91 dscl . merge /groups/${g} users ${euser}
732     done
733 vapier 1.182 export IFS=${oldifs}
734 usata 1.91 else
735 vapier 1.182 einfo "Extra options are not supported on Darwin yet"
736 usata 1.91 einfo "Please report the ebuild along with the info below"
737 vapier 1.182 einfo "eextra: $@"
738 usata 1.91 die "Required function missing"
739     fi
740 vapier 1.182 ;;
741 flameeyes 1.220 *-freebsd*|*-dragonfly*)
742 vapier 1.182 if [[ -z $@ ]] ; then
743 ka0ttic 1.108 pw useradd ${euser} ${opts} \
744     -c "added by portage for ${PN}" \
745     die "enewuser failed"
746     else
747 vapier 1.182 einfo " - Extra: $@"
748 ka0ttic 1.108 pw useradd ${euser} ${opts} \
749 vapier 1.182 "$@" || die "enewuser failed"
750 ka0ttic 1.108 fi
751 vapier 1.182 ;;
752 flameeyes 1.207
753     *-netbsd*)
754     if [[ -z $@ ]] ; then
755     useradd ${opts} ${euser} || die "enewuser failed"
756     else
757     einfo " - Extra: $@"
758     useradd ${opts} ${euser} "$@" || die "enewuser failed"
759     fi
760     ;;
761 flameeyes 1.218
762     *-openbsd*)
763     if [[ -z $@ ]] ; then
764     useradd -u ${euid} -s ${eshell} \
765     -d ${ehome} -c "Added by portage for ${PN}" \
766     -g ${egroups} ${euser} || die "enewuser failed"
767     else
768     einfo " - Extra: $@"
769     useradd -u ${euid} -s ${eshell} \
770     -d ${ehome} -c "Added by portage for ${PN}" \
771     -g ${egroups} ${euser} "$@" || die "enewuser failed"
772     fi
773     ;;
774    
775 vapier 1.182 *)
776     if [[ -z $@ ]] ; then
777 cardoe 1.345 useradd -r ${opts} \
778 usata 1.91 -c "added by portage for ${PN}" \
779 grobian 1.321 ${euser} \
780 usata 1.91 || die "enewuser failed"
781     else
782 vapier 1.182 einfo " - Extra: $@"
783 cardoe 1.345 useradd -r ${opts} "$@" \
784 grobian 1.321 ${euser} \
785 usata 1.91 || die "enewuser failed"
786     fi
787 vapier 1.182 ;;
788     esac
789 vapier 1.23
790 vapier 1.193 if [[ ! -e ${ROOT}/${ehome} ]] ; then
791     einfo " - Creating ${ehome} in ${ROOT}"
792     mkdir -p "${ROOT}/${ehome}"
793     chown ${euser} "${ROOT}/${ehome}"
794     chmod 755 "${ROOT}/${ehome}"
795 vapier 1.23 fi
796 vapier 1.193
797     export SANDBOX_ON=${oldsandbox}
798 vapier 1.23 }
799    
800 vapier 1.283 # @FUNCTION: enewgroup
801     # @USAGE: <group> [gid]
802     # @DESCRIPTION:
803     # This function does not require you to understand how to properly add a
804     # group to the system. Just give it a group name to add and enewgroup will
805     # do the rest. You may specify the gid for the group or allow the group to
806     # allocate the next available one.
807 vapier 1.23 enewgroup() {
808 vapier 1.233 case ${EBUILD_PHASE} in
809     unpack|compile|test|install)
810     eerror "'enewgroup()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
811     eerror "Package fails at QA and at life. Please file a bug."
812     die "Bad package! enewgroup is only for use in pkg_* functions!"
813     esac
814    
815 vapier 1.23 # get the group
816     local egroup="$1"; shift
817 azarah 1.59 if [ -z "${egroup}" ]
818     then
819 vapier 1.23 eerror "No group specified !"
820     die "Cannot call enewgroup without a group"
821     fi
822    
823     # see if group already exists
824 agriffis 1.256 if [[ -n $(egetent group "${egroup}") ]]; then
825 vapier 1.23 return 0
826     fi
827 wolf31o2 1.44 einfo "Adding group '${egroup}' to your system ..."
828 vapier 1.23
829     # options to pass to useradd
830 azarah 1.59 local opts=
831 vapier 1.23
832     # handle gid
833     local egid="$1"; shift
834 azarah 1.59 if [ ! -z "${egid}" ]
835     then
836     if [ "${egid}" -gt 0 ]
837     then
838 usata 1.91 if [ -z "`egetent group ${egid}`" ]
839 vapier 1.83 then
840 flameeyes 1.205 if [[ "${CHOST}" == *-darwin* ]]; then
841 usata 1.91 opts="${opts} ${egid}"
842     else
843     opts="${opts} -g ${egid}"
844     fi
845 vapier 1.83 else
846 vapier 1.84 egid="next available; requested gid taken"
847 vapier 1.83 fi
848 vapier 1.23 else
849     eerror "Groupid given but is not greater than 0 !"
850     die "${egid} is not a valid GID"
851     fi
852     else
853     egid="next available"
854     fi
855     einfo " - Groupid: ${egid}"
856    
857     # handle extra
858     local eextra="$@"
859     opts="${opts} ${eextra}"
860    
861     # add the group
862 azarah 1.59 local oldsandbox="${SANDBOX_ON}"
863 vapier 1.23 export SANDBOX_ON="0"
864 flameeyes 1.205 case ${CHOST} in
865     *-darwin*)
866 usata 1.91 if [ ! -z "${eextra}" ];
867     then
868 vapier 1.179 einfo "Extra options are not supported on Darwin/OS X yet"
869 usata 1.91 einfo "Please report the ebuild along with the info below"
870     einfo "eextra: ${eextra}"
871     die "Required function missing"
872     fi
873 mr_bones_ 1.100
874 usata 1.91 # If we need the next available
875     case ${egid} in
876 flameeyes 1.205 *[!0-9]*) # Non numeric
877 agriffis 1.256 for ((egid = 101; egid <= 999; egid++)); do
878     [[ -z $(egetent group ${egid}) ]] && break
879 usata 1.91 done
880     esac
881     dscl . create /groups/${egroup} gid ${egid}
882 mr_bones_ 1.100 dscl . create /groups/${egroup} passwd '*'
883 flameeyes 1.205 ;;
884    
885 flameeyes 1.220 *-freebsd*|*-dragonfly*)
886 ka0ttic 1.108 case ${egid} in
887     *[!0-9]*) # Non numeric
888 agriffis 1.256 for ((egid = 101; egid <= 999; egid++)); do
889     [[ -z $(egetent group ${egid}) ]] && break
890 ka0ttic 1.108 done
891     esac
892     pw groupadd ${egroup} -g ${egid} || die "enewgroup failed"
893 flameeyes 1.205 ;;
894 flameeyes 1.206
895     *-netbsd*)
896     case ${egid} in
897     *[!0-9]*) # Non numeric
898 agriffis 1.256 for ((egid = 101; egid <= 999; egid++)); do
899     [[ -z $(egetent group ${egid}) ]] && break
900 flameeyes 1.206 done
901     esac
902 flameeyes 1.207 groupadd -g ${egid} ${egroup} || die "enewgroup failed"
903 flameeyes 1.206 ;;
904    
905 flameeyes 1.205 *)
906 cardoe 1.345 # We specify -r so that we get a GID in the system range from login.defs
907     groupadd -r ${opts} ${egroup} || die "enewgroup failed"
908 flameeyes 1.205 ;;
909     esac
910 vapier 1.23 export SANDBOX_ON="${oldsandbox}"
911 vapier 1.24 }
912    
913 vapier 1.283 # @FUNCTION: edos2unix
914     # @USAGE: <file> [more files ...]
915     # @DESCRIPTION:
916     # A handy replacement for dos2unix, recode, fixdos, etc... This allows you
917     # to remove all of these text utilities from DEPEND variables because this
918     # is a script based solution. Just give it a list of files to convert and
919     # they will all be changed from the DOS CRLF format to the UNIX LF format.
920 vapier 1.24 edos2unix() {
921 vapier 1.263 echo "$@" | xargs sed -i 's/\r$//'
922 vapier 1.39 }
923    
924     # Make a desktop file !
925     # Great for making those icons in kde/gnome startmenu !
926 flameeyes 1.266 # Amaze your friends ! Get the women ! Join today !
927 vapier 1.39 #
928 vapier 1.341 # make_desktop_entry(<command>, [name], [icon], [type], [fields])
929 vapier 1.39 #
930 tupone 1.238 # binary: what command does the app run with ?
931 vapier 1.39 # name: the name that will show up in the menu
932     # icon: give your little like a pretty little icon ...
933 vapier 1.118 # this can be relative (to /usr/share/pixmaps) or
934     # a full path to an icon
935 flameeyes 1.266 # type: what kind of application is this ? for categories:
936 vapier 1.284 # http://standards.freedesktop.org/menu-spec/latest/apa.html
937 vapier 1.341 # fields: extra fields to append to the desktop file; a printf string
938 vapier 1.39 make_desktop_entry() {
939 vapier 1.341 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
940 vapier 1.39
941 vapier 1.158 local exec=${1}
942     local name=${2:-${PN}}
943 wolf31o2 1.293 local icon=${3:-${PN}}
944 vapier 1.158 local type=${4}
945 vapier 1.341 local fields=${5}
946 vapier 1.158
947     if [[ -z ${type} ]] ; then
948     local catmaj=${CATEGORY%%-*}
949     local catmin=${CATEGORY##*-}
950     case ${catmaj} in
951     app)
952     case ${catmin} in
953 vapier 1.284 accessibility) type=Accessibility;;
954 vapier 1.338 admin) type=System;;
955     antivirus) type=System;;
956     arch) type=Archiving;;
957     backup) type=Archiving;;
958     cdr) type=DiscBurning;;
959     dicts) type=Dictionary;;
960     doc) type=Documentation;;
961     editors) type=TextEditor;;
962     emacs) type=TextEditor;;
963     emulation) type=Emulator;;
964     laptop) type=HardwareSettings;;
965     office) type=Office;;
966     pda) type=PDA;;
967     vim) type=TextEditor;;
968     xemacs) type=TextEditor;;
969 vapier 1.158 esac
970 azarah 1.59 ;;
971 vapier 1.158
972     dev)
973 vapier 1.159 type="Development"
974 vapier 1.158 ;;
975    
976     games)
977     case ${catmin} in
978 wolf31o2 1.265 action|fps) type=ActionGame;;
979 vapier 1.338 arcade) type=ArcadeGame;;
980     board) type=BoardGame;;
981     emulation) type=Emulator;;
982     kids) type=KidsGame;;
983     puzzle) type=LogicGame;;
984     roguelike) type=RolePlaying;;
985     rpg) type=RolePlaying;;
986 vapier 1.158 simulation) type=Simulation;;
987 vapier 1.338 sports) type=SportsGame;;
988     strategy) type=StrategyGame;;
989 vapier 1.158 esac
990 vapier 1.159 type="Game;${type}"
991 vapier 1.158 ;;
992    
993 vapier 1.284 gnome)
994     type="Gnome;GTK"
995     ;;
996    
997     kde)
998     type="KDE;Qt"
999     ;;
1000    
1001 vapier 1.158 mail)
1002 vapier 1.159 type="Network;Email"
1003 vapier 1.158 ;;
1004    
1005     media)
1006     case ${catmin} in
1007 vapier 1.339 gfx)
1008     type=Graphics
1009     ;;
1010     *)
1011     case ${catmin} in
1012     radio) type=Tuner;;
1013     sound) type=Audio;;
1014     tv) type=TV;;
1015     video) type=Video;;
1016     esac
1017     type="AudioVideo;${type}"
1018     ;;
1019 vapier 1.158 esac
1020 wolf31o2 1.65 ;;
1021 vapier 1.158
1022     net)
1023     case ${catmin} in
1024     dialup) type=Dialup;;
1025 vapier 1.338 ftp) type=FileTransfer;;
1026     im) type=InstantMessaging;;
1027     irc) type=IRCClient;;
1028     mail) type=Email;;
1029     news) type=News;;
1030     nntp) type=News;;
1031     p2p) type=FileTransfer;;
1032     voip) type=Telephony;;
1033 vapier 1.158 esac
1034 vapier 1.159 type="Network;${type}"
1035 vapier 1.158 ;;
1036    
1037     sci)
1038     case ${catmin} in
1039 vapier 1.284 astro*) type=Astronomy;;
1040 vapier 1.338 bio*) type=Biology;;
1041     calc*) type=Calculator;;
1042     chem*) type=Chemistry;;
1043 vapier 1.284 elec*) type=Electronics;;
1044 vapier 1.338 geo*) type=Geology;;
1045     math*) type=Math;;
1046 vapier 1.284 physics) type=Physics;;
1047     visual*) type=DataVisualization;;
1048 vapier 1.159 esac
1049 abcd 1.336 type="Education;Science;${type}"
1050 vapier 1.158 ;;
1051    
1052 vapier 1.284 sys)
1053     type="System"
1054     ;;
1055    
1056 vapier 1.158 www)
1057     case ${catmin} in
1058     client) type=WebBrowser;;
1059     esac
1060 abcd 1.336 type="Network;${type}"
1061 azarah 1.59 ;;
1062 vapier 1.158
1063 azarah 1.59 *)
1064     type=
1065     ;;
1066 vapier 1.39 esac
1067     fi
1068 carlo 1.177 if [ "${SLOT}" == "0" ] ; then
1069     local desktop_name="${PN}"
1070     else
1071     local desktop_name="${PN}-${SLOT}"
1072     fi
1073 vapier 1.272 local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
1074 vapier 1.271 #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
1075 vapier 1.39
1076 abcd 1.336 # Don't append another ";" when a valid category value is provided.
1077     type=${type%;}${type:+;}
1078    
1079     eshopts_push -s extglob
1080     if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
1081     ewarn "As described in the Icon Theme Specification, icon file extensions are not"
1082     ewarn "allowed in .desktop files if the value is not an absolute path."
1083     icon=${icon%.@(xpm|png|svg)}
1084     fi
1085     eshopts_pop
1086    
1087 vapier 1.271 cat <<-EOF > "${desktop}"
1088     [Desktop Entry]
1089     Name=${name}
1090     Type=Application
1091     Comment=${DESCRIPTION}
1092     Exec=${exec}
1093     TryExec=${exec%% *}
1094     Icon=${icon}
1095 abcd 1.336 Categories=${type}
1096 vapier 1.271 EOF
1097 vapier 1.39
1098 vapier 1.341 if [[ ${fields:-=} != *=* ]] ; then
1099     # 5th arg used to be value to Path=
1100     ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
1101     fields="Path=${fields}"
1102     fi
1103 vapier 1.342 [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
1104 wolf31o2 1.293
1105 vapier 1.204 (
1106     # wrap the env here so that the 'insinto' call
1107     # doesn't corrupt the env of the caller
1108     insinto /usr/share/applications
1109     doins "${desktop}"
1110 vapier 1.340 ) || die "installing desktop file failed"
1111 danarmak 1.32 }
1112    
1113 vapier 1.283 # @FUNCTION: validate_desktop_entries
1114     # @USAGE: [directories]
1115     # @MAINTAINER:
1116     # Carsten Lohrke <carlo@gentoo.org>
1117     # @DESCRIPTION:
1118 carlo 1.278 # Validate desktop entries using desktop-file-utils
1119 carlo 1.277 validate_desktop_entries() {
1120     if [[ -x /usr/bin/desktop-file-validate ]] ; then
1121     einfo "Checking desktop entry validity"
1122     local directories=""
1123 carlo 1.279 for d in /usr/share/applications $@ ; do
1124     [[ -d ${D}${d} ]] && directories="${directories} ${D}${d}"
1125 carlo 1.277 done
1126 carlo 1.279 if [[ -n ${directories} ]] ; then
1127     for FILE in $(find ${directories} -name "*\.desktop" \
1128     -not -path '*.hidden*' | sort -u 2>/dev/null)
1129     do
1130     local temp=$(desktop-file-validate ${FILE} | grep -v "warning:" | \
1131     sed -e "s|error: ||" -e "s|${FILE}:|--|g" )
1132     [[ -n $temp ]] && elog ${temp/--/${FILE/${D}/}:}
1133     done
1134     fi
1135 carlo 1.277 echo ""
1136     else
1137     einfo "Passing desktop entry validity check. Install dev-util/desktop-file-utils, if you want to help to improve Gentoo."
1138     fi
1139     }
1140    
1141 vapier 1.283 # @FUNCTION: make_session_desktop
1142 vapier 1.314 # @USAGE: <title> <command> [command args...]
1143 vapier 1.283 # @DESCRIPTION:
1144     # Make a GDM/KDM Session file. The title is the file to execute to start the
1145     # Window Manager. The command is the name of the Window Manager.
1146 vapier 1.314 #
1147     # You can set the name of the file via the ${wm} variable.
1148 lanius 1.133 make_session_desktop() {
1149 vapier 1.314 [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
1150     [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
1151 lanius 1.133
1152 vapier 1.167 local title=$1
1153     local command=$2
1154 vapier 1.314 local desktop=${T}/${wm:-${PN}}.desktop
1155     shift 2
1156 lanius 1.133
1157 vapier 1.271 cat <<-EOF > "${desktop}"
1158     [Desktop Entry]
1159     Name=${title}
1160     Comment=This session logs you into ${title}
1161 vapier 1.314 Exec=${command} $*
1162 vapier 1.271 TryExec=${command}
1163 vapier 1.314 Type=XSession
1164 vapier 1.271 EOF
1165 lanius 1.133
1166 vapier 1.271 (
1167     # wrap the env here so that the 'insinto' call
1168     # doesn't corrupt the env of the caller
1169 lanius 1.133 insinto /usr/share/xsessions
1170     doins "${desktop}"
1171 vapier 1.271 )
1172 lanius 1.133 }
1173    
1174 vapier 1.283 # @FUNCTION: domenu
1175     # @USAGE: <menus>
1176     # @DESCRIPTION:
1177     # Install the list of .desktop menu files into the appropriate directory
1178     # (/usr/share/applications).
1179 lanius 1.133 domenu() {
1180 vapier 1.271 (
1181     # wrap the env here so that the 'insinto' call
1182     # doesn't corrupt the env of the caller
1183     local i j ret=0
1184 lanius 1.133 insinto /usr/share/applications
1185 vapier 1.167 for i in "$@" ; do
1186     if [[ -f ${i} ]] ; then
1187     doins "${i}"
1188 vapier 1.271 ((ret+=$?))
1189 vapier 1.167 elif [[ -d ${i} ]] ; then
1190     for j in "${i}"/*.desktop ; do
1191     doins "${j}"
1192 vapier 1.271 ((ret+=$?))
1193 lanius 1.133 done
1194 vapier 1.285 else
1195     ((++ret))
1196 swegener 1.190 fi
1197 lanius 1.133 done
1198 vapier 1.271 exit ${ret}
1199     )
1200 lanius 1.133 }
1201 vapier 1.283
1202     # @FUNCTION: newmenu
1203     # @USAGE: <menu> <newname>
1204     # @DESCRIPTION:
1205     # Like all other new* functions, install the specified menu as newname.
1206 vapier 1.167 newmenu() {
1207 vapier 1.271 (
1208     # wrap the env here so that the 'insinto' call
1209     # doesn't corrupt the env of the caller
1210 vapier 1.167 insinto /usr/share/applications
1211 vapier 1.271 newins "$@"
1212     )
1213 vapier 1.167 }
1214 lanius 1.133
1215 vapier 1.283 # @FUNCTION: doicon
1216     # @USAGE: <list of icons>
1217     # @DESCRIPTION:
1218     # Install the list of icons into the icon directory (/usr/share/pixmaps).
1219     # This is useful in conjunction with creating desktop/menu files.
1220 lanius 1.133 doicon() {
1221 vapier 1.271 (
1222     # wrap the env here so that the 'insinto' call
1223     # doesn't corrupt the env of the caller
1224     local i j ret
1225 lanius 1.133 insinto /usr/share/pixmaps
1226 vapier 1.167 for i in "$@" ; do
1227     if [[ -f ${i} ]] ; then
1228     doins "${i}"
1229 vapier 1.271 ((ret+=$?))
1230 vapier 1.167 elif [[ -d ${i} ]] ; then
1231     for j in "${i}"/*.png ; do
1232     doins "${j}"
1233 vapier 1.271 ((ret+=$?))
1234 lanius 1.133 done
1235 vapier 1.285 else
1236     ((++ret))
1237 swegener 1.190 fi
1238 lanius 1.133 done
1239 vapier 1.271 exit ${ret}
1240     )
1241 lanius 1.133 }
1242 vapier 1.283
1243     # @FUNCTION: newicon
1244     # @USAGE: <icon> <newname>
1245     # @DESCRIPTION:
1246     # Like all other new* functions, install the specified icon as newname.
1247 vapier 1.167 newicon() {
1248 vapier 1.271 (
1249     # wrap the env here so that the 'insinto' call
1250     # doesn't corrupt the env of the caller
1251 vapier 1.167 insinto /usr/share/pixmaps
1252 vapier 1.271 newins "$@"
1253     )
1254 vapier 1.167 }
1255 lanius 1.133
1256 vapier 1.70 # for internal use only (unpack_pdv and unpack_makeself)
1257     find_unpackable_file() {
1258 vapier 1.196 local src=$1
1259     if [[ -z ${src} ]] ; then
1260     src=${DISTDIR}/${A}
1261 vapier 1.50 else
1262 vapier 1.196 if [[ -e ${DISTDIR}/${src} ]] ; then
1263     src=${DISTDIR}/${src}
1264     elif [[ -e ${PWD}/${src} ]] ; then
1265     src=${PWD}/${src}
1266     elif [[ -e ${src} ]] ; then
1267     src=${src}
1268 vapier 1.50 fi
1269     fi
1270 vapier 1.196 [[ ! -e ${src} ]] && return 1
1271 vapier 1.70 echo "${src}"
1272     }
1273    
1274 vapier 1.283 # @FUNCTION: unpack_pdv
1275     # @USAGE: <file to unpack> <size of off_t>
1276     # @DESCRIPTION:
1277 vapier 1.70 # Unpack those pesky pdv generated files ...
1278     # They're self-unpacking programs with the binary package stuffed in
1279     # the middle of the archive. Valve seems to use it a lot ... too bad
1280     # it seems to like to segfault a lot :(. So lets take it apart ourselves.
1281 swegener 1.286 #
1282 vapier 1.283 # You have to specify the off_t size ... I have no idea how to extract that
1283     # information out of the binary executable myself. Basically you pass in
1284     # the size of the off_t type (in bytes) on the machine that built the pdv
1285     # archive.
1286 vapier 1.70 #
1287 vapier 1.283 # One way to determine this is by running the following commands:
1288 ulm 1.288 #
1289     # @CODE
1290     # strings <pdv archive> | grep lseek
1291     # strace -elseek <pdv archive>
1292     # @CODE
1293     #
1294 vapier 1.283 # Basically look for the first lseek command (we do the strings/grep because
1295     # sometimes the function call is _llseek or something) and steal the 2nd
1296     # parameter. Here is an example:
1297 ulm 1.288 #
1298     # @CODE
1299     # vapier@vapier 0 pdv_unpack # strings hldsupdatetool.bin | grep lseek
1300     # lseek
1301     # vapier@vapier 0 pdv_unpack # strace -elseek ./hldsupdatetool.bin
1302     # lseek(3, -4, SEEK_END) = 2981250
1303     # @CODE
1304     #
1305 vapier 1.283 # Thus we would pass in the value of '4' as the second parameter.
1306 vapier 1.70 unpack_pdv() {
1307 vapier 1.271 local src=$(find_unpackable_file "$1")
1308 vapier 1.196 local sizeoff_t=$2
1309 vapier 1.70
1310 vapier 1.196 [[ -z ${src} ]] && die "Could not locate source for '$1'"
1311     [[ -z ${sizeoff_t} ]] && die "No idea what off_t size was used for this pdv :("
1312 vapier 1.70
1313 vapier 1.212 local shrtsrc=$(basename "${src}")
1314 vapier 1.70 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1315 vapier 1.271 local metaskip=$(tail -c ${sizeoff_t} "${src}" | hexdump -e \"%i\")
1316     local tailskip=$(tail -c $((${sizeoff_t}*2)) "${src}" | head -c ${sizeoff_t} | hexdump -e \"%i\")
1317 vapier 1.70
1318     # grab metadata for debug reasons
1319 vapier 1.271 local metafile=$(emktemp)
1320     tail -c +$((${metaskip}+1)) "${src}" > "${metafile}"
1321 vapier 1.70
1322     # rip out the final file name from the metadata
1323 vapier 1.271 local datafile=$(tail -c +$((${metaskip}+1)) "${src}" | strings | head -n 1)
1324     datafile=$(basename "${datafile}")
1325 vapier 1.70
1326 vapier 1.71 # now lets uncompress/untar the file if need be
1327 vapier 1.271 local tmpfile=$(emktemp)
1328 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null | head -c 512 > ${tmpfile}
1329 vapier 1.71
1330 vapier 1.271 local iscompressed=$(file -b "${tmpfile}")
1331     if [[ ${iscompressed:0:8} == "compress" ]] ; then
1332 vapier 1.71 iscompressed=1
1333     mv ${tmpfile}{,.Z}
1334     gunzip ${tmpfile}
1335     else
1336     iscompressed=0
1337     fi
1338 vapier 1.271 local istar=$(file -b "${tmpfile}")
1339     if [[ ${istar:0:9} == "POSIX tar" ]] ; then
1340 vapier 1.71 istar=1
1341     else
1342     istar=0
1343     fi
1344    
1345     #for some reason gzip dies with this ... dd cant provide buffer fast enough ?
1346     #dd if=${src} ibs=${metaskip} count=1 \
1347     # | dd ibs=${tailskip} skip=1 \
1348     # | gzip -dc \
1349     # > ${datafile}
1350     if [ ${iscompressed} -eq 1 ] ; then
1351     if [ ${istar} -eq 1 ] ; then
1352     tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1353     | head -c $((${metaskip}-${tailskip})) \
1354     | tar -xzf -
1355     else
1356 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1357     | head -c $((${metaskip}-${tailskip})) \
1358     | gzip -dc \
1359     > ${datafile}
1360 vapier 1.71 fi
1361     else
1362     if [ ${istar} -eq 1 ] ; then
1363     tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1364     | head -c $((${metaskip}-${tailskip})) \
1365 vapier 1.73 | tar --no-same-owner -xf -
1366 vapier 1.71 else
1367 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1368     | head -c $((${metaskip}-${tailskip})) \
1369     > ${datafile}
1370 vapier 1.71 fi
1371     fi
1372     true
1373     #[ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1374 vapier 1.70 #assert "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1375     }
1376    
1377 vapier 1.283 # @FUNCTION: unpack_makeself
1378     # @USAGE: [file to unpack] [offset] [tail|dd]
1379     # @DESCRIPTION:
1380 vapier 1.70 # Unpack those pesky makeself generated files ...
1381     # They're shell scripts with the binary package tagged onto
1382     # the end of the archive. Loki utilized the format as does
1383     # many other game companies.
1384 swegener 1.286 #
1385 vapier 1.283 # If the file is not specified, then ${A} is used. If the
1386     # offset is not specified then we will attempt to extract
1387     # the proper offset from the script itself.
1388 vapier 1.70 unpack_makeself() {
1389 vapier 1.217 local src_input=${1:-${A}}
1390     local src=$(find_unpackable_file "${src_input}")
1391 vapier 1.196 local skip=$2
1392     local exe=$3
1393    
1394 vapier 1.217 [[ -z ${src} ]] && die "Could not locate source for '${src_input}'"
1395 vapier 1.50
1396 vapier 1.196 local shrtsrc=$(basename "${src}")
1397 vapier 1.41 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1398 vapier 1.212 if [[ -z ${skip} ]] ; then
1399 mr_bones_ 1.343 local ver=$(grep -m1 -a '#.*Makeself' "${src}" | awk '{print $NF}')
1400 vapier 1.41 local skip=0
1401 vapier 1.112 exe=tail
1402 vapier 1.41 case ${ver} in
1403 wolf31o2 1.240 1.5.*|1.6.0-nv) # tested 1.5.{3,4,5} ... guessing 1.5.x series is same
1404 vapier 1.112 skip=$(grep -a ^skip= "${src}" | cut -d= -f2)
1405 vapier 1.41 ;;
1406     2.0|2.0.1)
1407 vapier 1.112 skip=$(grep -a ^$'\t'tail "${src}" | awk '{print $2}' | cut -b2-)
1408 vapier 1.41 ;;
1409 wolf31o2 1.48 2.1.1)
1410 vapier 1.112 skip=$(grep -a ^offset= "${src}" | awk '{print $2}' | cut -b2-)
1411 vapier 1.344 (( skip++ ))
1412 wolf31o2 1.48 ;;
1413 vapier 1.49 2.1.2)
1414 vapier 1.112 skip=$(grep -a ^offset= "${src}" | awk '{print $3}' | head -n 1)
1415 vapier 1.344 (( skip++ ))
1416 vapier 1.49 ;;
1417 wolf31o2 1.48 2.1.3)
1418 vapier 1.112 skip=`grep -a ^offset= "${src}" | awk '{print $3}'`
1419 vapier 1.344 (( skip++ ))
1420 vapier 1.41 ;;
1421 wolf31o2 1.211 2.1.4|2.1.5)
1422 vapier 1.112 skip=$(grep -a offset=.*head.*wc "${src}" | awk '{print $3}' | head -n 1)
1423     skip=$(head -n ${skip} "${src}" | wc -c)
1424     exe="dd"
1425     ;;
1426 vapier 1.41 *)
1427     eerror "I'm sorry, but I was unable to support the Makeself file."
1428     eerror "The version I detected was '${ver}'."
1429     eerror "Please file a bug about the file ${shrtsrc} at"
1430     eerror "http://bugs.gentoo.org/ so that support can be added."
1431     die "makeself version '${ver}' not supported"
1432     ;;
1433     esac
1434     debug-print "Detected Makeself version ${ver} ... using ${skip} as offset"
1435     fi
1436 vapier 1.112 case ${exe} in
1437     tail) exe="tail -n +${skip} '${src}'";;
1438 vapier 1.344 dd) exe="dd ibs=${skip} skip=1 if='${src}'";;
1439 vapier 1.112 *) die "makeself cant handle exe '${exe}'"
1440     esac
1441 vapier 1.41
1442 vapier 1.68 # lets grab the first few bytes of the file to figure out what kind of archive it is
1443 vapier 1.356 local filetype tmpfile=$(emktemp)
1444 vapier 1.112 eval ${exe} 2>/dev/null | head -c 512 > "${tmpfile}"
1445 vapier 1.356 filetype=$(file -b "${tmpfile}") || die
1446 vapier 1.68 case ${filetype} in
1447 vapier 1.257 *tar\ archive*)
1448 vapier 1.112 eval ${exe} | tar --no-same-owner -xf -
1449 vapier 1.68 ;;
1450     bzip2*)
1451 vapier 1.112 eval ${exe} | bzip2 -dc | tar --no-same-owner -xf -
1452 mr_bones_ 1.69 ;;
1453 vapier 1.68 gzip*)
1454 vapier 1.112 eval ${exe} | tar --no-same-owner -xzf -
1455 vapier 1.68 ;;
1456 vapier 1.93 compress*)
1457 vapier 1.112 eval ${exe} | gunzip | tar --no-same-owner -xf -
1458 vapier 1.93 ;;
1459 vapier 1.68 *)
1460 vapier 1.93 eerror "Unknown filetype \"${filetype}\" ?"
1461 vapier 1.68 false
1462     ;;
1463     esac
1464     assert "failure unpacking (${filetype}) makeself ${shrtsrc} ('${ver}' +${skip})"
1465 wolf31o2 1.56 }
1466    
1467 vapier 1.283 # @FUNCTION: check_license
1468     # @USAGE: [license]
1469     # @DESCRIPTION:
1470     # Display a license for user to accept. If no license is
1471     # specified, then ${LICENSE} is used.
1472 wolf31o2 1.56 check_license() {
1473 vapier 1.60 local lic=$1
1474     if [ -z "${lic}" ] ; then
1475     lic="${PORTDIR}/licenses/${LICENSE}"
1476 wolf31o2 1.56 else
1477 wolf31o2 1.199 if [ -e "${PORTDIR}/licenses/${lic}" ] ; then
1478     lic="${PORTDIR}/licenses/${lic}"
1479     elif [ -e "${PWD}/${lic}" ] ; then
1480     lic="${PWD}/${lic}"
1481     elif [ -e "${lic}" ] ; then
1482     lic="${lic}"
1483 wolf31o2 1.56 fi
1484     fi
1485 vapier 1.64 local l="`basename ${lic}`"
1486 wolf31o2 1.56
1487 vapier 1.60 # here is where we check for the licenses the user already
1488     # accepted ... if we don't find a match, we make the user accept
1489     local alic
1490 vapier 1.322 eshopts_push -o noglob # so that bash doesn't expand "*"
1491 wolf31o2 1.104 for alic in ${ACCEPT_LICENSE} ; do
1492 wolf31o2 1.255 if [[ ${alic} == ${l} ]]; then
1493 vapier 1.322 eshopts_pop
1494 wolf31o2 1.106 return 0
1495     fi
1496 vapier 1.60 done
1497 vapier 1.322 eshopts_pop
1498 zmedico 1.324 [ ! -f "${lic}" ] && die "Could not find requested license ${lic}"
1499 vapier 1.60
1500 vapier 1.271 local licmsg=$(emktemp)
1501     cat <<-EOF > ${licmsg}
1502     **********************************************************
1503     The following license outlines the terms of use of this
1504     package. You MUST accept this license for installation to
1505     continue. When you are done viewing, hit 'q'. If you
1506     CTRL+C out of this, the install will not run!
1507     **********************************************************
1508 swegener 1.286
1509 vapier 1.271 EOF
1510 vapier 1.60 cat ${lic} >> ${licmsg}
1511     ${PAGER:-less} ${licmsg} || die "Could not execute pager (${PAGER}) to accept ${lic}"
1512 vapier 1.64 einfon "Do you accept the terms of this license (${l})? [yes/no] "
1513 vapier 1.60 read alic
1514     case ${alic} in
1515     yes|Yes|y|Y)
1516     return 0
1517     ;;
1518     *)
1519     echo;echo;echo
1520     eerror "You MUST accept the license to continue! Exiting!"
1521     die "Failed to accept license"
1522     ;;
1523     esac
1524 vapier 1.23 }
1525 vapier 1.75
1526 vapier 1.283 # @FUNCTION: cdrom_get_cds
1527     # @USAGE: <file on cd1> [file on cd2] [file on cd3] [...]
1528     # @DESCRIPTION:
1529 vapier 1.75 # Aquire cd(s) for those lovely cd-based emerges. Yes, this violates
1530     # the whole 'non-interactive' policy, but damnit I want CD support !
1531 swegener 1.286 #
1532 vapier 1.283 # With these cdrom functions we handle all the user interaction and
1533     # standardize everything. All you have to do is call cdrom_get_cds()
1534 vapier 1.75 # and when the function returns, you can assume that the cd has been
1535     # found at CDROM_ROOT.
1536 swegener 1.286 #
1537 vapier 1.283 # The function will attempt to locate a cd based upon a file that is on
1538     # the cd. The more files you give this function, the more cds
1539     # the cdrom functions will handle.
1540 swegener 1.286 #
1541 vapier 1.283 # Normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2',
1542     # etc... If you want to give the cds better names, then just export
1543 vapier 1.243 # the appropriate CDROM_NAME variable before calling cdrom_get_cds().
1544 vapier 1.283 # Use CDROM_NAME for one cd, or CDROM_NAME_# for multiple cds. You can
1545     # also use the CDROM_NAME_SET bash array.
1546 swegener 1.286 #
1547 vapier 1.283 # For those multi cd ebuilds, see the cdrom_load_next_cd() function.
1548 vapier 1.75 cdrom_get_cds() {
1549     # first we figure out how many cds we're dealing with by
1550     # the # of files they gave us
1551     local cdcnt=0
1552     local f=
1553     for f in "$@" ; do
1554 vapier 1.214 ((++cdcnt))
1555 vapier 1.75 export CDROM_CHECK_${cdcnt}="$f"
1556     done
1557     export CDROM_TOTAL_CDS=${cdcnt}
1558     export CDROM_CURRENT_CD=1
1559    
1560     # now we see if the user gave use CD_ROOT ...
1561     # if they did, let's just believe them that it's correct
1562 vapier 1.215 if [[ -n ${CD_ROOT}${CD_ROOT_1} ]] ; then
1563 vapier 1.75 local var=
1564     cdcnt=0
1565 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1566 vapier 1.214 ((++cdcnt))
1567 vapier 1.75 var="CD_ROOT_${cdcnt}"
1568 vapier 1.215 [[ -z ${!var} ]] && var="CD_ROOT"
1569 vapier 1.131 if [[ -z ${!var} ]] ; then
1570 vapier 1.75 eerror "You must either use just the CD_ROOT"
1571     eerror "or specify ALL the CD_ROOT_X variables."
1572     eerror "In this case, you will need ${CDROM_TOTAL_CDS} CD_ROOT_X variables."
1573     die "could not locate CD_ROOT_${cdcnt}"
1574     fi
1575     done
1576 vapier 1.215 export CDROM_ROOT=${CD_ROOT_1:-${CD_ROOT}}
1577 vapier 1.75 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1578 vapier 1.215 export CDROM_SET=-1
1579     for f in ${CDROM_CHECK_1//:/ } ; do
1580     ((++CDROM_SET))
1581 cardoe 1.346 [[ -e ${CDROM_ROOT}/${f} ]] && break
1582 vapier 1.215 done
1583     export CDROM_MATCH=${f}
1584 vapier 1.75 return
1585     fi
1586    
1587 vapier 1.215 # User didn't help us out so lets make sure they know they can
1588     # simplify the whole process ...
1589 vapier 1.131 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1590 vapier 1.215 einfo "This ebuild will need the ${CDROM_NAME:-cdrom for ${PN}}"
1591 vapier 1.75 echo
1592     einfo "If you do not have the CD, but have the data files"
1593     einfo "mounted somewhere on your filesystem, just export"
1594     einfo "the variable CD_ROOT so that it points to the"
1595     einfo "directory containing the files."
1596     echo
1597 vapier 1.132 einfo "For example:"
1598     einfo "export CD_ROOT=/mnt/cdrom"
1599     echo
1600 vapier 1.75 else
1601 vapier 1.243 if [[ -n ${CDROM_NAME_SET} ]] ; then
1602     # Translate the CDROM_NAME_SET array into CDROM_NAME_#
1603     cdcnt=0
1604     while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1605     ((++cdcnt))
1606     export CDROM_NAME_${cdcnt}="${CDROM_NAME_SET[$((${cdcnt}-1))]}"
1607     done
1608     fi
1609    
1610 vapier 1.75 einfo "This package will need access to ${CDROM_TOTAL_CDS} cds."
1611     cdcnt=0
1612 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1613 vapier 1.214 ((++cdcnt))
1614 vapier 1.75 var="CDROM_NAME_${cdcnt}"
1615 vapier 1.131 [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}"
1616 vapier 1.75 done
1617     echo
1618     einfo "If you do not have the CDs, but have the data files"
1619     einfo "mounted somewhere on your filesystem, just export"
1620     einfo "the following variables so they point to the right place:"
1621 nyhm 1.347 einfon ""
1622 vapier 1.75 cdcnt=0
1623 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1624 vapier 1.214 ((++cdcnt))
1625 vapier 1.75 echo -n " CD_ROOT_${cdcnt}"
1626     done
1627     echo
1628     einfo "Or, if you have all the files in the same place, or"
1629     einfo "you only have one cdrom, you can export CD_ROOT"
1630     einfo "and that place will be used as the same data source"
1631     einfo "for all the CDs."
1632     echo
1633 vapier 1.132 einfo "For example:"
1634     einfo "export CD_ROOT_1=/mnt/cdrom"
1635     echo
1636 vapier 1.75 fi
1637 vapier 1.215
1638 vapier 1.214 export CDROM_SET=""
1639 vapier 1.75 export CDROM_CURRENT_CD=0
1640     cdrom_load_next_cd
1641     }
1642    
1643 vapier 1.283 # @FUNCTION: cdrom_load_next_cd
1644     # @DESCRIPTION:
1645     # Some packages are so big they come on multiple CDs. When you're done reading
1646     # files off a CD and want access to the next one, just call this function.
1647     # Again, all the messy details of user interaction are taken care of for you.
1648     # Once this returns, just read the variable CDROM_ROOT for the location of the
1649     # mounted CD. Note that you can only go forward in the CD list, so make sure
1650     # you only call this function when you're done using the current CD.
1651 vapier 1.75 cdrom_load_next_cd() {
1652 vapier 1.215 local var
1653     ((++CDROM_CURRENT_CD))
1654 vapier 1.79
1655 vapier 1.75 unset CDROM_ROOT
1656 vapier 1.215 var=CD_ROOT_${CDROM_CURRENT_CD}
1657     [[ -z ${!var} ]] && var="CD_ROOT"
1658 vapier 1.131 if [[ -z ${!var} ]] ; then
1659 vapier 1.75 var="CDROM_CHECK_${CDROM_CURRENT_CD}"
1660 vapier 1.215 _cdrom_locate_file_on_cd ${!var}
1661 vapier 1.75 else
1662 vapier 1.131 export CDROM_ROOT=${!var}
1663 vapier 1.75 fi
1664    
1665     einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1666     }
1667    
1668     # this is used internally by the cdrom_get_cds() and cdrom_load_next_cd()
1669     # functions. this should *never* be called from an ebuild.
1670     # all it does is try to locate a give file on a cd ... if the cd isn't
1671     # found, then a message asking for the user to insert the cdrom will be
1672     # displayed and we'll hang out here until:
1673     # (1) the file is found on a mounted cdrom
1674     # (2) the user hits CTRL+C
1675 vapier 1.215 _cdrom_locate_file_on_cd() {
1676 vapier 1.214 local mline=""
1677 wolf31o2 1.296 local showedmsg=0 showjolietmsg=0
1678 vapier 1.214
1679 vapier 1.131 while [[ -z ${CDROM_ROOT} ]] ; do
1680 vapier 1.214 local i=0
1681     local -a cdset=(${*//:/ })
1682     if [[ -n ${CDROM_SET} ]] ; then
1683     cdset=(${cdset[${CDROM_SET}]})
1684     fi
1685    
1686     while [[ -n ${cdset[${i}]} ]] ; do
1687     local dir=$(dirname ${cdset[${i}]})
1688     local file=$(basename ${cdset[${i}]})
1689    
1690 uberlord 1.259 local point= node= fs= foo=
1691     while read point node fs foo ; do
1692 nyhm 1.281 [[ " cd9660 iso9660 udf " != *" ${fs} "* ]] && \
1693 uberlord 1.264 ! [[ ${fs} == "subfs" && ",${opts}," == *",fs=cdfss,"* ]] \
1694     && continue
1695 uberlord 1.259 point=${point//\040/ }
1696 vapier 1.292 [[ ! -d ${point}/${dir} ]] && continue
1697 uberlord 1.259 [[ -z $(find "${point}/${dir}" -maxdepth 1 -iname "${file}") ]] && continue
1698     export CDROM_ROOT=${point}
1699     export CDROM_SET=${i}
1700     export CDROM_MATCH=${cdset[${i}]}
1701     return
1702 kanaka 1.262 done <<< "$(get_mounts)"
1703 vapier 1.214
1704     ((++i))
1705 vapier 1.75 done
1706    
1707 vapier 1.214 echo
1708     if [[ ${showedmsg} -eq 0 ]] ; then
1709     if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1710     if [[ -z ${CDROM_NAME} ]] ; then
1711     einfo "Please insert+mount the cdrom for ${PN} now !"
1712     else
1713     einfo "Please insert+mount the ${CDROM_NAME} cdrom now !"
1714     fi
1715     else
1716     if [[ -z ${CDROM_NAME_1} ]] ; then
1717     einfo "Please insert+mount cd #${CDROM_CURRENT_CD} for ${PN} now !"
1718 vapier 1.75 else
1719 vapier 1.214 local var="CDROM_NAME_${CDROM_CURRENT_CD}"
1720     einfo "Please insert+mount the ${!var} cdrom now !"
1721 vapier 1.75 fi
1722     fi
1723 vapier 1.214 showedmsg=1
1724 vapier 1.75 fi
1725 vapier 1.214 einfo "Press return to scan for the cd again"
1726     einfo "or hit CTRL+C to abort the emerge."
1727     echo
1728 wolf31o2 1.296 if [[ ${showjolietmsg} -eq 0 ]] ; then
1729     showjolietmsg=1
1730     else
1731     ewarn "If you are having trouble with the detection"
1732     ewarn "of your CD, it is possible that you do not have"
1733     ewarn "Joliet support enabled in your kernel. Please"
1734     ewarn "check that CONFIG_JOLIET is enabled in your kernel."
1735     ebeep 5
1736     fi
1737 vapier 1.222 read || die "something is screwed with your system"
1738 vapier 1.75 done
1739     }
1740 vapier 1.92
1741 vapier 1.287 # @FUNCTION: strip-linguas
1742     # @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1743     # @DESCRIPTION:
1744 mr_bones_ 1.100 # Make sure that LINGUAS only contains languages that
1745 vapier 1.287 # a package can support. The first form allows you to
1746     # specify a list of LINGUAS. The -i builds a list of po
1747     # files found in all the directories and uses the
1748     # intersection of the lists. The -u builds a list of po
1749     # files found in all the directories and uses the union
1750     # of the lists.
1751 vapier 1.92 strip-linguas() {
1752 vapier 1.242 local ls newls nols
1753 vapier 1.154 if [[ $1 == "-i" ]] || [[ $1 == "-u" ]] ; then
1754     local op=$1; shift
1755 vapier 1.315 ls=$(find "$1" -name '*.po' -exec basename {} .po ';'); shift
1756 vapier 1.92 local d f
1757     for d in "$@" ; do
1758 vapier 1.154 if [[ ${op} == "-u" ]] ; then
1759     newls=${ls}
1760 vapier 1.92 else
1761     newls=""
1762     fi
1763 vapier 1.315 for f in $(find "$d" -name '*.po' -exec basename {} .po ';') ; do
1764 vapier 1.154 if [[ ${op} == "-i" ]] ; then
1765 ssuominen 1.358 has ${f} ${ls} && newls="${newls} ${f}"
1766 vapier 1.92 else
1767 ssuominen 1.358 has ${f} ${ls} || newls="${newls} ${f}"
1768 vapier 1.92 fi
1769     done
1770 vapier 1.154 ls=${newls}
1771 vapier 1.92 done
1772     else
1773 vapier 1.236 ls="$@"
1774 vapier 1.92 fi
1775    
1776 vapier 1.242 nols=""
1777 vapier 1.92 newls=""
1778     for f in ${LINGUAS} ; do
1779 ssuominen 1.358 if has ${f} ${ls} ; then
1780 vapier 1.120 newls="${newls} ${f}"
1781 vapier 1.92 else
1782 vapier 1.242 nols="${nols} ${f}"
1783 vapier 1.92 fi
1784     done
1785 vapier 1.244 [[ -n ${nols} ]] \
1786 vapier 1.316 && ewarn "Sorry, but ${PN} does not support the LINGUAS:" ${nols}
1787 vapier 1.237 export LINGUAS=${newls:1}
1788 vapier 1.92 }
1789 iggy 1.110
1790 vapier 1.283 # @FUNCTION: preserve_old_lib
1791     # @USAGE: <libs to preserve> [more libs]
1792     # @DESCRIPTION:
1793     # These functions are useful when a lib in your package changes ABI SONAME.
1794     # An example might be from libogg.so.0 to libogg.so.1. Removing libogg.so.0
1795 eradicator 1.111 # would break packages that link against it. Most people get around this
1796     # by using the portage SLOT mechanism, but that is not always a relevant
1797 vapier 1.283 # solution, so instead you can call this from pkg_preinst. See also the
1798     # preserve_old_lib_notify function.
1799 eradicator 1.111 preserve_old_lib() {
1800 vapier 1.268 if [[ ${EBUILD_PHASE} != "preinst" ]] ; then
1801 vapier 1.267 eerror "preserve_old_lib() must be called from pkg_preinst() only"
1802 vapier 1.276 die "Invalid preserve_old_lib() usage"
1803 vapier 1.267 fi
1804     [[ -z $1 ]] && die "Usage: preserve_old_lib <library to preserve> [more libraries to preserve]"
1805    
1806 vapier 1.297 # let portage worry about it
1807     has preserve-libs ${FEATURES} && return 0
1808    
1809 vapier 1.267 local lib dir
1810     for lib in "$@" ; do
1811     [[ -e ${ROOT}/${lib} ]] || continue
1812     dir=${lib%/*}
1813     dodir ${dir} || die "dodir ${dir} failed"
1814     cp "${ROOT}"/${lib} "${D}"/${lib} || die "cp ${lib} failed"
1815     touch "${D}"/${lib}
1816     done
1817 eradicator 1.111 }
1818    
1819 vapier 1.283 # @FUNCTION: preserve_old_lib_notify
1820     # @USAGE: <libs to notify> [more libs]
1821     # @DESCRIPTION:
1822     # Spit helpful messages about the libraries preserved by preserve_old_lib.
1823 eradicator 1.111 preserve_old_lib_notify() {
1824 vapier 1.268 if [[ ${EBUILD_PHASE} != "postinst" ]] ; then
1825 vapier 1.267 eerror "preserve_old_lib_notify() must be called from pkg_postinst() only"
1826 vapier 1.276 die "Invalid preserve_old_lib_notify() usage"
1827 vapier 1.267 fi
1828    
1829 vapier 1.297 # let portage worry about it
1830     has preserve-libs ${FEATURES} && return 0
1831    
1832 vapier 1.267 local lib notice=0
1833     for lib in "$@" ; do
1834     [[ -e ${ROOT}/${lib} ]] || continue
1835     if [[ ${notice} -eq 0 ]] ; then
1836     notice=1
1837     ewarn "Old versions of installed libraries were detected on your system."
1838     ewarn "In order to avoid breaking packages that depend on these old libs,"
1839     ewarn "the libraries are not being removed. You need to run revdep-rebuild"
1840     ewarn "in order to remove these old dependencies. If you do not have this"
1841     ewarn "helper program, simply emerge the 'gentoolkit' package."
1842     ewarn
1843     fi
1844 vapier 1.355 # temp hack for #348634 #357225
1845     [[ ${PN} == "mpfr" ]] && lib=${lib##*/}
1846 vapier 1.352 ewarn " # revdep-rebuild --library '${lib}'"
1847 vapier 1.267 done
1848 vapier 1.291 if [[ ${notice} -eq 1 ]] ; then
1849     ewarn
1850     ewarn "Once you've finished running revdep-rebuild, it should be safe to"
1851 vapier 1.300 ewarn "delete the old libraries. Here is a copy & paste for the lazy:"
1852     for lib in "$@" ; do
1853     ewarn " # rm '${lib}'"
1854     done
1855 vapier 1.291 fi
1856 eradicator 1.111 }
1857 vapier 1.125
1858 vapier 1.283 # @FUNCTION: built_with_use
1859     # @USAGE: [--hidden] [--missing <action>] [-a|-o] <DEPEND ATOM> <List of USE flags>
1860     # @DESCRIPTION:
1861 betelgeuse 1.329 #
1862     # Deprecated: Use EAPI 2 use deps in DEPEND|RDEPEND and with has_version calls.
1863     #
1864 vapier 1.283 # A temporary hack until portage properly supports DEPENDing on USE
1865     # flags being enabled in packages. This will check to see if the specified
1866     # DEPEND atom was built with the specified list of USE flags. The
1867     # --missing option controls the behavior if called on a package that does
1868     # not actually support the defined USE flags (aka listed in IUSE).
1869     # The default is to abort (call die). The -a and -o flags control
1870     # the requirements of the USE flags. They correspond to "and" and "or"
1871     # logic. So the -a flag means all listed USE flags must be enabled
1872 opfer 1.302 # while the -o flag means at least one of the listed IUSE flags must be
1873 vapier 1.283 # enabled. The --hidden option is really for internal use only as it
1874     # means the USE flag we're checking is hidden expanded, so it won't be found
1875     # in IUSE like normal USE flags.
1876 swegener 1.286 #
1877 vapier 1.283 # Remember that this function isn't terribly intelligent so order of optional
1878     # flags matter.
1879 vapier 1.125 built_with_use() {
1880 vapier 1.275 local hidden="no"
1881     if [[ $1 == "--hidden" ]] ; then
1882     hidden="yes"
1883     shift
1884     fi
1885    
1886 vapier 1.269 local missing_action="die"
1887     if [[ $1 == "--missing" ]] ; then
1888     missing_action=$2
1889     shift ; shift
1890     case ${missing_action} in
1891     true|false|die) ;;
1892     *) die "unknown action '${missing_action}'";;
1893     esac
1894     fi
1895    
1896 vapier 1.130 local opt=$1
1897     [[ ${opt:0:1} = "-" ]] && shift || opt="-a"
1898    
1899     local PKG=$(best_version $1)
1900 vapier 1.247 [[ -z ${PKG} ]] && die "Unable to resolve $1 to an installed package"
1901 vapier 1.130 shift
1902    
1903 vapier 1.213 local USEFILE=${ROOT}/var/db/pkg/${PKG}/USE
1904 vapier 1.249 local IUSEFILE=${ROOT}/var/db/pkg/${PKG}/IUSE
1905 vapier 1.213
1906 cardoe 1.273 # if the IUSE file doesn't exist, the read will error out, we need to handle
1907     # this gracefully
1908 vapier 1.275 if [[ ! -e ${USEFILE} ]] || [[ ! -e ${IUSEFILE} && ${hidden} == "no" ]] ; then
1909 cardoe 1.273 case ${missing_action} in
1910     true) return 0;;
1911     false) return 1;;
1912     die) die "Unable to determine what USE flags $PKG was built with";;
1913     esac
1914     fi
1915    
1916 vapier 1.275 if [[ ${hidden} == "no" ]] ; then
1917 zmedico 1.301 local IUSE_BUILT=( $(<"${IUSEFILE}") )
1918 vapier 1.275 # Don't check USE_EXPAND #147237
1919     local expand
1920     for expand in $(echo ${USE_EXPAND} | tr '[:upper:]' '[:lower:]') ; do
1921     if [[ $1 == ${expand}_* ]] ; then
1922     expand=""
1923     break
1924     fi
1925     done
1926     if [[ -n ${expand} ]] ; then
1927 zmedico 1.301 if ! has $1 ${IUSE_BUILT[@]#[-+]} ; then
1928 vapier 1.275 case ${missing_action} in
1929     true) return 0;;
1930     false) return 1;;
1931     die) die "$PKG does not actually support the $1 USE flag!";;
1932     esac
1933     fi
1934 vapier 1.269 fi
1935 vapier 1.250 fi
1936 vapier 1.249
1937 vapier 1.125 local USE_BUILT=$(<${USEFILE})
1938 vapier 1.130 while [[ $# -gt 0 ]] ; do
1939     if [[ ${opt} = "-o" ]] ; then
1940     has $1 ${USE_BUILT} && return 0
1941     else
1942     has $1 ${USE_BUILT} || return 1
1943     fi
1944 vapier 1.125 shift
1945     done
1946 vapier 1.130 [[ ${opt} = "-a" ]]
1947 vapier 1.125 }
1948 vapier 1.126
1949 vapier 1.289 # @FUNCTION: epunt_cxx
1950 vapier 1.283 # @USAGE: [dir to scan]
1951     # @DESCRIPTION:
1952     # Many configure scripts wrongly bail when a C++ compiler could not be
1953     # detected. If dir is not specified, then it defaults to ${S}.
1954     #
1955     # http://bugs.gentoo.org/73450
1956 vapier 1.126 epunt_cxx() {
1957 vapier 1.127 local dir=$1
1958     [[ -z ${dir} ]] && dir=${S}
1959     ebegin "Removing useless C++ checks"
1960     local f
1961 vapier 1.294 find "${dir}" -name configure | while read f ; do
1962     patch --no-backup-if-mismatch -p0 "${f}" "${PORTDIR}/eclass/ELT-patches/nocxx/nocxx.patch" > /dev/null
1963 vapier 1.127 done
1964     eend 0
1965 vapier 1.126 }
1966 ka0ttic 1.143
1967 vapier 1.283 # @FUNCTION: make_wrapper
1968 wolf31o2 1.295 # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
1969 vapier 1.283 # @DESCRIPTION:
1970     # Create a shell wrapper script named wrapper in installpath
1971     # (defaults to the bindir) to execute target (default of wrapper) by
1972     # first optionally setting LD_LIBRARY_PATH to the colon-delimited
1973     # libpaths followed by optionally changing directory to chdir.
1974 wolf31o2 1.160 make_wrapper() {
1975 wolf31o2 1.164 local wrapper=$1 bin=$2 chdir=$3 libdir=$4 path=$5
1976 wolf31o2 1.160 local tmpwrapper=$(emktemp)
1977 vapier 1.202 # We don't want to quote ${bin} so that people can pass complex
1978     # things as $bin ... "./someprog --args"
1979 wolf31o2 1.160 cat << EOF > "${tmpwrapper}"
1980     #!/bin/sh
1981 vapier 1.201 cd "${chdir:-.}"
1982 vapier 1.210 if [ -n "${libdir}" ] ; then
1983     if [ "\${LD_LIBRARY_PATH+set}" = "set" ] ; then
1984     export LD_LIBRARY_PATH="\${LD_LIBRARY_PATH}:${libdir}"
1985     else
1986     export LD_LIBRARY_PATH="${libdir}"
1987     fi
1988 vapier 1.201 fi
1989 vapier 1.202 exec ${bin} "\$@"
1990 wolf31o2 1.160 EOF
1991     chmod go+rx "${tmpwrapper}"
1992 vapier 1.201 if [[ -n ${path} ]] ; then
1993 vapier 1.283 (
1994 vapier 1.201 exeinto "${path}"
1995 wolf31o2 1.164 newexe "${tmpwrapper}" "${wrapper}"
1996 vapier 1.283 ) || die
1997 wolf31o2 1.164 else
1998 vapier 1.283 newbin "${tmpwrapper}" "${wrapper}" || die
1999 wolf31o2 1.164 fi
2000 wolf31o2 1.160 }
2001 mr_bones_ 1.311
2002 vapier 1.351 # @FUNCTION: path_exists
2003     # @USAGE: [-a|-o] <paths>
2004     # @DESCRIPTION:
2005     # Check if the specified paths exist. Works for all types of paths
2006     # (files/dirs/etc...). The -a and -o flags control the requirements
2007     # of the paths. They correspond to "and" and "or" logic. So the -a
2008     # flag means all the paths must exist while the -o flag means at least
2009     # one of the paths must exist. The default behavior is "and". If no
2010     # paths are specified, then the return value is "false".
2011     path_exists() {
2012     local opt=$1
2013     [[ ${opt} == -[ao] ]] && shift || opt="-a"
2014    
2015     # no paths -> return false
2016     # same behavior as: [[ -e "" ]]
2017     [[ $# -eq 0 ]] && return 1
2018    
2019     local p r=0
2020     for p in "$@" ; do
2021     [[ -e ${p} ]]
2022     : $(( r += $? ))
2023     done
2024    
2025     case ${opt} in
2026     -a) return $(( r != 0 )) ;;
2027     -o) return $(( r == $# )) ;;
2028     esac
2029     }

  ViewVC Help
Powered by ViewVC 1.1.20