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

Contents of /eclass/eutils.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.360 - (hide annotations) (download)
Sun Aug 7 23:35:28 2011 UTC (2 years, 11 months ago) by vapier
Branch: MAIN
Changes since 1.359: +11 -2 lines
epatch: log exit status of `patch` command #375983 by Toralf Förster

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.360 # $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.359 2011/07/20 05:46:46 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.318 epatch_user() {
445     [[ $# -ne 0 ]] && die "epatch_user takes no options"
446    
447     # don't clobber any EPATCH vars that the parent might want
448 zmedico 1.323 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
449 vapier 1.318 for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do
450     EPATCH_SOURCE=${base}/${CTARGET}/${check}
451     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
452     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
453     if [[ -d ${EPATCH_SOURCE} ]] ; then
454     EPATCH_SOURCE=${EPATCH_SOURCE} \
455     EPATCH_SUFFIX="patch" \
456     EPATCH_FORCE="yes" \
457     EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
458     epatch
459 vapier 1.349 return 0
460 vapier 1.318 fi
461     done
462 vapier 1.349 return 1
463 vapier 1.318 }
464 azarah 1.26
465 vapier 1.283 # @FUNCTION: emktemp
466     # @USAGE: [temp dir]
467     # @DESCRIPTION:
468 vapier 1.52 # Cheap replacement for when debianutils (and thus mktemp)
469 vapier 1.283 # does not exist on the users system.
470 vapier 1.117 emktemp() {
471 vapier 1.119 local exe="touch"
472 vapier 1.194 [[ $1 == -d ]] && exe="mkdir" && shift
473     local topdir=$1
474 mr_bones_ 1.100
475 vapier 1.194 if [[ -z ${topdir} ]] ; then
476     [[ -z ${T} ]] \
477 vapier 1.117 && topdir="/tmp" \
478 vapier 1.194 || topdir=${T}
479 vapier 1.117 fi
480    
481 vapier 1.280 if ! type -P mktemp > /dev/null ; then
482     # system lacks `mktemp` so we have to fake it
483 vapier 1.117 local tmp=/
484 vapier 1.194 while [[ -e ${tmp} ]] ; do
485     tmp=${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM}
486 vapier 1.117 done
487 vapier 1.194 ${exe} "${tmp}" || ${exe} -p "${tmp}"
488 vapier 1.117 echo "${tmp}"
489 vapier 1.52 else
490 vapier 1.280 # the args here will give slightly wierd names on BSD,
491     # but should produce a usable file on all userlands
492 flameeyes 1.223 if [[ ${exe} == "touch" ]] ; then
493 vapier 1.280 TMPDIR="${topdir}" mktemp -t tmp.XXXXXXXXXX
494 flameeyes 1.223 else
495 vapier 1.280 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
496 flameeyes 1.223 fi
497 vapier 1.52 fi
498     }
499    
500 vapier 1.283 # @FUNCTION: egetent
501     # @USAGE: <database> <key>
502     # @MAINTAINER:
503     # base-system@gentoo.org (Linux)
504     # Joe Jezak <josejx@gmail.com> (OS X)
505     # usata@gentoo.org (OS X)
506     # Aaron Walker <ka0ttic@gentoo.org> (FreeBSD)
507     # @DESCRIPTION:
508 grobian 1.310 # Small wrapper for getent (Linux),
509     # nidump (< Mac OS X 10.5), dscl (Mac OS X 10.5),
510 ka0ttic 1.108 # and pw (FreeBSD) used in enewuser()/enewgroup()
511 usata 1.91 egetent() {
512 flameeyes 1.205 case ${CHOST} in
513 grobian 1.319 *-darwin[678])
514 grobian 1.310 case "$2" in
515     *[!0-9]*) # Non numeric
516 betelgeuse 1.357 nidump $1 . | awk -F":" "{ if (\$1 ~ /^$2\$/) {print \$0;exit;} }"
517 grobian 1.310 ;;
518     *) # Numeric
519 grobian 1.319 nidump $1 . | awk -F":" "{ if (\$3 == $2) {print \$0;exit;} }"
520 grobian 1.310 ;;
521     esac
522     ;;
523 flameeyes 1.205 *-darwin*)
524 grobian 1.319 local mytype=$1
525     [[ "passwd" == $mytype ]] && mytype="Users"
526     [[ "group" == $mytype ]] && mytype="Groups"
527 usata 1.91 case "$2" in
528 flameeyes 1.205 *[!0-9]*) # Non numeric
529 grobian 1.319 dscl . -read /$mytype/$2 2>/dev/null |grep RecordName
530 usata 1.91 ;;
531 flameeyes 1.205 *) # Numeric
532 grobian 1.319 local mykey="UniqueID"
533     [[ $mytype == "Groups" ]] && mykey="PrimaryGroupID"
534     dscl . -search /$mytype $mykey $2 2>/dev/null
535 usata 1.91 ;;
536     esac
537 flameeyes 1.205 ;;
538 flameeyes 1.220 *-freebsd*|*-dragonfly*)
539 ka0ttic 1.203 local opts action="user"
540     [[ $1 == "passwd" ]] || action="group"
541    
542     # lookup by uid/gid
543     if [[ $2 == [[:digit:]]* ]] ; then
544     [[ ${action} == "user" ]] && opts="-u" || opts="-g"
545 ka0ttic 1.108 fi
546 ka0ttic 1.203
547     pw show ${action} ${opts} "$2" -q
548 flameeyes 1.205 ;;
549 flameeyes 1.218 *-netbsd*|*-openbsd*)
550 flameeyes 1.206 grep "$2:\*:" /etc/$1
551     ;;
552 flameeyes 1.205 *)
553     type -p nscd >& /dev/null && nscd -i "$1"
554 vapier 1.107 getent "$1" "$2"
555 flameeyes 1.205 ;;
556     esac
557 usata 1.91 }
558    
559 vapier 1.283 # @FUNCTION: enewuser
560     # @USAGE: <user> [uid] [shell] [homedir] [groups] [params]
561     # @DESCRIPTION:
562     # Same as enewgroup, you are not required to understand how to properly add
563     # a user to the system. The only required parameter is the username.
564     # Default uid is (pass -1 for this) next available, default shell is
565     # /bin/false, default homedir is /dev/null, there are no default groups,
566     # and default params sets the comment as 'added by portage for ${PN}'.
567 vapier 1.23 enewuser() {
568 vapier 1.233 case ${EBUILD_PHASE} in
569     unpack|compile|test|install)
570     eerror "'enewuser()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
571     eerror "Package fails at QA and at life. Please file a bug."
572     die "Bad package! enewuser is only for use in pkg_* functions!"
573     esac
574    
575 vapier 1.23 # get the username
576 vapier 1.182 local euser=$1; shift
577     if [[ -z ${euser} ]] ; then
578 vapier 1.23 eerror "No username specified !"
579     die "Cannot call enewuser without a username"
580     fi
581    
582 vapier 1.84 # lets see if the username already exists
583 agriffis 1.256 if [[ -n $(egetent passwd "${euser}") ]] ; then
584 vapier 1.23 return 0
585     fi
586 wolf31o2 1.44 einfo "Adding user '${euser}' to your system ..."
587 vapier 1.23
588     # options to pass to useradd
589 azarah 1.59 local opts=
590 vapier 1.23
591     # handle uid
592 vapier 1.182 local euid=$1; shift
593 agriffis 1.256 if [[ -n ${euid} && ${euid} != -1 ]] ; then
594 vapier 1.182 if [[ ${euid} -gt 0 ]] ; then
595 agriffis 1.256 if [[ -n $(egetent passwd ${euid}) ]] ; then
596 vapier 1.84 euid="next"
597 vapier 1.82 fi
598 vapier 1.23 else
599     eerror "Userid given but is not greater than 0 !"
600     die "${euid} is not a valid UID"
601     fi
602     else
603 vapier 1.84 euid="next"
604     fi
605 vapier 1.182 if [[ ${euid} == "next" ]] ; then
606 agriffis 1.256 for ((euid = 101; euid <= 999; euid++)); do
607 vapier 1.182 [[ -z $(egetent passwd ${euid}) ]] && break
608 vapier 1.84 done
609 vapier 1.23 fi
610 vapier 1.84 opts="${opts} -u ${euid}"
611 vapier 1.23 einfo " - Userid: ${euid}"
612    
613     # handle shell
614 vapier 1.182 local eshell=$1; shift
615     if [[ ! -z ${eshell} ]] && [[ ${eshell} != "-1" ]] ; then
616 vapier 1.221 if [[ ! -e ${ROOT}${eshell} ]] ; then
617 vapier 1.23 eerror "A shell was specified but it does not exist !"
618 vapier 1.221 die "${eshell} does not exist in ${ROOT}"
619     fi
620     if [[ ${eshell} == */false || ${eshell} == */nologin ]] ; then
621     eerror "Do not specify ${eshell} yourself, use -1"
622     die "Pass '-1' as the shell parameter"
623 vapier 1.23 fi
624     else
625 vapier 1.204 for shell in /sbin/nologin /usr/sbin/nologin /bin/false /usr/bin/false /dev/null ; do
626     [[ -x ${ROOT}${shell} ]] && break
627 flameeyes 1.198 done
628    
629 vapier 1.204 if [[ ${shell} == "/dev/null" ]] ; then
630 flameeyes 1.253 eerror "Unable to identify the shell to use, proceeding with userland default."
631     case ${USERLAND} in
632     GNU) shell="/bin/false" ;;
633     BSD) shell="/sbin/nologin" ;;
634     Darwin) shell="/usr/sbin/nologin" ;;
635     *) die "Unable to identify the default shell for userland ${USERLAND}"
636     esac
637 flameeyes 1.198 fi
638    
639     eshell=${shell}
640 vapier 1.23 fi
641     einfo " - Shell: ${eshell}"
642     opts="${opts} -s ${eshell}"
643    
644     # handle homedir
645 vapier 1.182 local ehome=$1; shift
646     if [[ -z ${ehome} ]] || [[ ${ehome} == "-1" ]] ; then
647 azarah 1.59 ehome="/dev/null"
648 vapier 1.23 fi
649     einfo " - Home: ${ehome}"
650     opts="${opts} -d ${ehome}"
651    
652     # handle groups
653 vapier 1.182 local egroups=$1; shift
654     if [[ ! -z ${egroups} ]] ; then
655     local oldifs=${IFS}
656 vapier 1.107 local defgroup="" exgroups=""
657    
658 vapier 1.23 export IFS=","
659 vapier 1.182 for g in ${egroups} ; do
660     export IFS=${oldifs}
661     if [[ -z $(egetent group "${g}") ]] ; then
662 vapier 1.85 eerror "You must add group ${g} to the system first"
663 vapier 1.23 die "${g} is not a valid GID"
664     fi
665 vapier 1.182 if [[ -z ${defgroup} ]] ; then
666     defgroup=${g}
667 vapier 1.107 else
668     exgroups="${exgroups},${g}"
669     fi
670 usata 1.115 export IFS=","
671 vapier 1.23 done
672 vapier 1.182 export IFS=${oldifs}
673 vapier 1.107
674     opts="${opts} -g ${defgroup}"
675 vapier 1.182 if [[ ! -z ${exgroups} ]] ; then
676 vapier 1.107 opts="${opts} -G ${exgroups:1}"
677     fi
678 vapier 1.23 else
679     egroups="(none)"
680     fi
681     einfo " - Groups: ${egroups}"
682    
683     # handle extra and add the user
684 vapier 1.182 local oldsandbox=${SANDBOX_ON}
685 vapier 1.23 export SANDBOX_ON="0"
686 flameeyes 1.205 case ${CHOST} in
687     *-darwin*)
688 usata 1.91 ### Make the user
689 vapier 1.182 if [[ -z $@ ]] ; then
690 usata 1.91 dscl . create /users/${euser} uid ${euid}
691     dscl . create /users/${euser} shell ${eshell}
692     dscl . create /users/${euser} home ${ehome}
693     dscl . create /users/${euser} realname "added by portage for ${PN}"
694     ### Add the user to the groups specified
695 vapier 1.182 local oldifs=${IFS}
696 usata 1.115 export IFS=","
697 vapier 1.182 for g in ${egroups} ; do
698 usata 1.91 dscl . merge /groups/${g} users ${euser}
699     done
700 vapier 1.182 export IFS=${oldifs}
701 usata 1.91 else
702 vapier 1.182 einfo "Extra options are not supported on Darwin yet"
703 usata 1.91 einfo "Please report the ebuild along with the info below"
704 vapier 1.182 einfo "eextra: $@"
705 usata 1.91 die "Required function missing"
706     fi
707 vapier 1.182 ;;
708 flameeyes 1.220 *-freebsd*|*-dragonfly*)
709 vapier 1.182 if [[ -z $@ ]] ; then
710 ka0ttic 1.108 pw useradd ${euser} ${opts} \
711     -c "added by portage for ${PN}" \
712     die "enewuser failed"
713     else
714 vapier 1.182 einfo " - Extra: $@"
715 ka0ttic 1.108 pw useradd ${euser} ${opts} \
716 vapier 1.182 "$@" || die "enewuser failed"
717 ka0ttic 1.108 fi
718 vapier 1.182 ;;
719 flameeyes 1.207
720     *-netbsd*)
721     if [[ -z $@ ]] ; then
722     useradd ${opts} ${euser} || die "enewuser failed"
723     else
724     einfo " - Extra: $@"
725     useradd ${opts} ${euser} "$@" || die "enewuser failed"
726     fi
727     ;;
728 flameeyes 1.218
729     *-openbsd*)
730     if [[ -z $@ ]] ; then
731     useradd -u ${euid} -s ${eshell} \
732     -d ${ehome} -c "Added by portage for ${PN}" \
733     -g ${egroups} ${euser} || die "enewuser failed"
734     else
735     einfo " - Extra: $@"
736     useradd -u ${euid} -s ${eshell} \
737     -d ${ehome} -c "Added by portage for ${PN}" \
738     -g ${egroups} ${euser} "$@" || die "enewuser failed"
739     fi
740     ;;
741    
742 vapier 1.182 *)
743     if [[ -z $@ ]] ; then
744 cardoe 1.345 useradd -r ${opts} \
745 usata 1.91 -c "added by portage for ${PN}" \
746 grobian 1.321 ${euser} \
747 usata 1.91 || die "enewuser failed"
748     else
749 vapier 1.182 einfo " - Extra: $@"
750 cardoe 1.345 useradd -r ${opts} "$@" \
751 grobian 1.321 ${euser} \
752 usata 1.91 || die "enewuser failed"
753     fi
754 vapier 1.182 ;;
755     esac
756 vapier 1.23
757 vapier 1.193 if [[ ! -e ${ROOT}/${ehome} ]] ; then
758     einfo " - Creating ${ehome} in ${ROOT}"
759     mkdir -p "${ROOT}/${ehome}"
760     chown ${euser} "${ROOT}/${ehome}"
761     chmod 755 "${ROOT}/${ehome}"
762 vapier 1.23 fi
763 vapier 1.193
764     export SANDBOX_ON=${oldsandbox}
765 vapier 1.23 }
766    
767 vapier 1.283 # @FUNCTION: enewgroup
768     # @USAGE: <group> [gid]
769     # @DESCRIPTION:
770     # This function does not require you to understand how to properly add a
771     # group to the system. Just give it a group name to add and enewgroup will
772     # do the rest. You may specify the gid for the group or allow the group to
773     # allocate the next available one.
774 vapier 1.23 enewgroup() {
775 vapier 1.233 case ${EBUILD_PHASE} in
776     unpack|compile|test|install)
777     eerror "'enewgroup()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
778     eerror "Package fails at QA and at life. Please file a bug."
779     die "Bad package! enewgroup is only for use in pkg_* functions!"
780     esac
781    
782 vapier 1.23 # get the group
783     local egroup="$1"; shift
784 azarah 1.59 if [ -z "${egroup}" ]
785     then
786 vapier 1.23 eerror "No group specified !"
787     die "Cannot call enewgroup without a group"
788     fi
789    
790     # see if group already exists
791 agriffis 1.256 if [[ -n $(egetent group "${egroup}") ]]; then
792 vapier 1.23 return 0
793     fi
794 wolf31o2 1.44 einfo "Adding group '${egroup}' to your system ..."
795 vapier 1.23
796     # options to pass to useradd
797 azarah 1.59 local opts=
798 vapier 1.23
799     # handle gid
800     local egid="$1"; shift
801 azarah 1.59 if [ ! -z "${egid}" ]
802     then
803     if [ "${egid}" -gt 0 ]
804     then
805 usata 1.91 if [ -z "`egetent group ${egid}`" ]
806 vapier 1.83 then
807 flameeyes 1.205 if [[ "${CHOST}" == *-darwin* ]]; then
808 usata 1.91 opts="${opts} ${egid}"
809     else
810     opts="${opts} -g ${egid}"
811     fi
812 vapier 1.83 else
813 vapier 1.84 egid="next available; requested gid taken"
814 vapier 1.83 fi
815 vapier 1.23 else
816     eerror "Groupid given but is not greater than 0 !"
817     die "${egid} is not a valid GID"
818     fi
819     else
820     egid="next available"
821     fi
822     einfo " - Groupid: ${egid}"
823    
824     # handle extra
825     local eextra="$@"
826     opts="${opts} ${eextra}"
827    
828     # add the group
829 azarah 1.59 local oldsandbox="${SANDBOX_ON}"
830 vapier 1.23 export SANDBOX_ON="0"
831 flameeyes 1.205 case ${CHOST} in
832     *-darwin*)
833 usata 1.91 if [ ! -z "${eextra}" ];
834     then
835 vapier 1.179 einfo "Extra options are not supported on Darwin/OS X yet"
836 usata 1.91 einfo "Please report the ebuild along with the info below"
837     einfo "eextra: ${eextra}"
838     die "Required function missing"
839     fi
840 mr_bones_ 1.100
841 usata 1.91 # If we need the next available
842     case ${egid} in
843 flameeyes 1.205 *[!0-9]*) # Non numeric
844 agriffis 1.256 for ((egid = 101; egid <= 999; egid++)); do
845     [[ -z $(egetent group ${egid}) ]] && break
846 usata 1.91 done
847     esac
848     dscl . create /groups/${egroup} gid ${egid}
849 mr_bones_ 1.100 dscl . create /groups/${egroup} passwd '*'
850 flameeyes 1.205 ;;
851    
852 flameeyes 1.220 *-freebsd*|*-dragonfly*)
853 ka0ttic 1.108 case ${egid} in
854     *[!0-9]*) # Non numeric
855 agriffis 1.256 for ((egid = 101; egid <= 999; egid++)); do
856     [[ -z $(egetent group ${egid}) ]] && break
857 ka0ttic 1.108 done
858     esac
859     pw groupadd ${egroup} -g ${egid} || die "enewgroup failed"
860 flameeyes 1.205 ;;
861 flameeyes 1.206
862     *-netbsd*)
863     case ${egid} in
864     *[!0-9]*) # Non numeric
865 agriffis 1.256 for ((egid = 101; egid <= 999; egid++)); do
866     [[ -z $(egetent group ${egid}) ]] && break
867 flameeyes 1.206 done
868     esac
869 flameeyes 1.207 groupadd -g ${egid} ${egroup} || die "enewgroup failed"
870 flameeyes 1.206 ;;
871    
872 flameeyes 1.205 *)
873 cardoe 1.345 # We specify -r so that we get a GID in the system range from login.defs
874     groupadd -r ${opts} ${egroup} || die "enewgroup failed"
875 flameeyes 1.205 ;;
876     esac
877 vapier 1.23 export SANDBOX_ON="${oldsandbox}"
878 vapier 1.24 }
879    
880 vapier 1.283 # @FUNCTION: edos2unix
881     # @USAGE: <file> [more files ...]
882     # @DESCRIPTION:
883     # A handy replacement for dos2unix, recode, fixdos, etc... This allows you
884     # to remove all of these text utilities from DEPEND variables because this
885     # is a script based solution. Just give it a list of files to convert and
886     # they will all be changed from the DOS CRLF format to the UNIX LF format.
887 vapier 1.24 edos2unix() {
888 vapier 1.263 echo "$@" | xargs sed -i 's/\r$//'
889 vapier 1.39 }
890    
891     # Make a desktop file !
892     # Great for making those icons in kde/gnome startmenu !
893 flameeyes 1.266 # Amaze your friends ! Get the women ! Join today !
894 vapier 1.39 #
895 vapier 1.341 # make_desktop_entry(<command>, [name], [icon], [type], [fields])
896 vapier 1.39 #
897 tupone 1.238 # binary: what command does the app run with ?
898 vapier 1.39 # name: the name that will show up in the menu
899     # icon: give your little like a pretty little icon ...
900 vapier 1.118 # this can be relative (to /usr/share/pixmaps) or
901     # a full path to an icon
902 flameeyes 1.266 # type: what kind of application is this ? for categories:
903 vapier 1.284 # http://standards.freedesktop.org/menu-spec/latest/apa.html
904 vapier 1.341 # fields: extra fields to append to the desktop file; a printf string
905 vapier 1.39 make_desktop_entry() {
906 vapier 1.341 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
907 vapier 1.39
908 vapier 1.158 local exec=${1}
909     local name=${2:-${PN}}
910 wolf31o2 1.293 local icon=${3:-${PN}}
911 vapier 1.158 local type=${4}
912 vapier 1.341 local fields=${5}
913 vapier 1.158
914     if [[ -z ${type} ]] ; then
915     local catmaj=${CATEGORY%%-*}
916     local catmin=${CATEGORY##*-}
917     case ${catmaj} in
918     app)
919     case ${catmin} in
920 vapier 1.284 accessibility) type=Accessibility;;
921 vapier 1.338 admin) type=System;;
922     antivirus) type=System;;
923     arch) type=Archiving;;
924     backup) type=Archiving;;
925     cdr) type=DiscBurning;;
926     dicts) type=Dictionary;;
927     doc) type=Documentation;;
928     editors) type=TextEditor;;
929     emacs) type=TextEditor;;
930     emulation) type=Emulator;;
931     laptop) type=HardwareSettings;;
932     office) type=Office;;
933     pda) type=PDA;;
934     vim) type=TextEditor;;
935     xemacs) type=TextEditor;;
936 vapier 1.158 esac
937 azarah 1.59 ;;
938 vapier 1.158
939     dev)
940 vapier 1.159 type="Development"
941 vapier 1.158 ;;
942    
943     games)
944     case ${catmin} in
945 wolf31o2 1.265 action|fps) type=ActionGame;;
946 vapier 1.338 arcade) type=ArcadeGame;;
947     board) type=BoardGame;;
948     emulation) type=Emulator;;
949     kids) type=KidsGame;;
950     puzzle) type=LogicGame;;
951     roguelike) type=RolePlaying;;
952     rpg) type=RolePlaying;;
953 vapier 1.158 simulation) type=Simulation;;
954 vapier 1.338 sports) type=SportsGame;;
955     strategy) type=StrategyGame;;
956 vapier 1.158 esac
957 vapier 1.159 type="Game;${type}"
958 vapier 1.158 ;;
959    
960 vapier 1.284 gnome)
961     type="Gnome;GTK"
962     ;;
963    
964     kde)
965     type="KDE;Qt"
966     ;;
967    
968 vapier 1.158 mail)
969 vapier 1.159 type="Network;Email"
970 vapier 1.158 ;;
971    
972     media)
973     case ${catmin} in
974 vapier 1.339 gfx)
975     type=Graphics
976     ;;
977     *)
978     case ${catmin} in
979     radio) type=Tuner;;
980     sound) type=Audio;;
981     tv) type=TV;;
982     video) type=Video;;
983     esac
984     type="AudioVideo;${type}"
985     ;;
986 vapier 1.158 esac
987 wolf31o2 1.65 ;;
988 vapier 1.158
989     net)
990     case ${catmin} in
991     dialup) type=Dialup;;
992 vapier 1.338 ftp) type=FileTransfer;;
993     im) type=InstantMessaging;;
994     irc) type=IRCClient;;
995     mail) type=Email;;
996     news) type=News;;
997     nntp) type=News;;
998     p2p) type=FileTransfer;;
999     voip) type=Telephony;;
1000 vapier 1.158 esac
1001 vapier 1.159 type="Network;${type}"
1002 vapier 1.158 ;;
1003    
1004     sci)
1005     case ${catmin} in
1006 vapier 1.284 astro*) type=Astronomy;;
1007 vapier 1.338 bio*) type=Biology;;
1008     calc*) type=Calculator;;
1009     chem*) type=Chemistry;;
1010 vapier 1.284 elec*) type=Electronics;;
1011 vapier 1.338 geo*) type=Geology;;
1012     math*) type=Math;;
1013 vapier 1.284 physics) type=Physics;;
1014     visual*) type=DataVisualization;;
1015 vapier 1.159 esac
1016 abcd 1.336 type="Education;Science;${type}"
1017 vapier 1.158 ;;
1018    
1019 vapier 1.284 sys)
1020     type="System"
1021     ;;
1022    
1023 vapier 1.158 www)
1024     case ${catmin} in
1025     client) type=WebBrowser;;
1026     esac
1027 abcd 1.336 type="Network;${type}"
1028 azarah 1.59 ;;
1029 vapier 1.158
1030 azarah 1.59 *)
1031     type=
1032     ;;
1033 vapier 1.39 esac
1034     fi
1035 carlo 1.177 if [ "${SLOT}" == "0" ] ; then
1036     local desktop_name="${PN}"
1037     else
1038     local desktop_name="${PN}-${SLOT}"
1039     fi
1040 vapier 1.272 local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
1041 vapier 1.271 #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
1042 vapier 1.39
1043 abcd 1.336 # Don't append another ";" when a valid category value is provided.
1044     type=${type%;}${type:+;}
1045    
1046     eshopts_push -s extglob
1047     if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
1048     ewarn "As described in the Icon Theme Specification, icon file extensions are not"
1049     ewarn "allowed in .desktop files if the value is not an absolute path."
1050     icon=${icon%.@(xpm|png|svg)}
1051     fi
1052     eshopts_pop
1053    
1054 vapier 1.271 cat <<-EOF > "${desktop}"
1055     [Desktop Entry]
1056     Name=${name}
1057     Type=Application
1058     Comment=${DESCRIPTION}
1059     Exec=${exec}
1060     TryExec=${exec%% *}
1061     Icon=${icon}
1062 abcd 1.336 Categories=${type}
1063 vapier 1.271 EOF
1064 vapier 1.39
1065 vapier 1.341 if [[ ${fields:-=} != *=* ]] ; then
1066     # 5th arg used to be value to Path=
1067     ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
1068     fields="Path=${fields}"
1069     fi
1070 vapier 1.342 [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
1071 wolf31o2 1.293
1072 vapier 1.204 (
1073     # wrap the env here so that the 'insinto' call
1074     # doesn't corrupt the env of the caller
1075     insinto /usr/share/applications
1076     doins "${desktop}"
1077 vapier 1.340 ) || die "installing desktop file failed"
1078 danarmak 1.32 }
1079    
1080 vapier 1.283 # @FUNCTION: validate_desktop_entries
1081     # @USAGE: [directories]
1082     # @MAINTAINER:
1083     # Carsten Lohrke <carlo@gentoo.org>
1084     # @DESCRIPTION:
1085 carlo 1.278 # Validate desktop entries using desktop-file-utils
1086 carlo 1.277 validate_desktop_entries() {
1087     if [[ -x /usr/bin/desktop-file-validate ]] ; then
1088     einfo "Checking desktop entry validity"
1089     local directories=""
1090 carlo 1.279 for d in /usr/share/applications $@ ; do
1091     [[ -d ${D}${d} ]] && directories="${directories} ${D}${d}"
1092 carlo 1.277 done
1093 carlo 1.279 if [[ -n ${directories} ]] ; then
1094     for FILE in $(find ${directories} -name "*\.desktop" \
1095     -not -path '*.hidden*' | sort -u 2>/dev/null)
1096     do
1097     local temp=$(desktop-file-validate ${FILE} | grep -v "warning:" | \
1098     sed -e "s|error: ||" -e "s|${FILE}:|--|g" )
1099     [[ -n $temp ]] && elog ${temp/--/${FILE/${D}/}:}
1100     done
1101     fi
1102 carlo 1.277 echo ""
1103     else
1104     einfo "Passing desktop entry validity check. Install dev-util/desktop-file-utils, if you want to help to improve Gentoo."
1105     fi
1106     }
1107    
1108 vapier 1.283 # @FUNCTION: make_session_desktop
1109 vapier 1.314 # @USAGE: <title> <command> [command args...]
1110 vapier 1.283 # @DESCRIPTION:
1111     # Make a GDM/KDM Session file. The title is the file to execute to start the
1112     # Window Manager. The command is the name of the Window Manager.
1113 vapier 1.314 #
1114     # You can set the name of the file via the ${wm} variable.
1115 lanius 1.133 make_session_desktop() {
1116 vapier 1.314 [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
1117     [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
1118 lanius 1.133
1119 vapier 1.167 local title=$1
1120     local command=$2
1121 vapier 1.314 local desktop=${T}/${wm:-${PN}}.desktop
1122     shift 2
1123 lanius 1.133
1124 vapier 1.271 cat <<-EOF > "${desktop}"
1125     [Desktop Entry]
1126     Name=${title}
1127     Comment=This session logs you into ${title}
1128 vapier 1.314 Exec=${command} $*
1129 vapier 1.271 TryExec=${command}
1130 vapier 1.314 Type=XSession
1131 vapier 1.271 EOF
1132 lanius 1.133
1133 vapier 1.271 (
1134     # wrap the env here so that the 'insinto' call
1135     # doesn't corrupt the env of the caller
1136 lanius 1.133 insinto /usr/share/xsessions
1137     doins "${desktop}"
1138 vapier 1.271 )
1139 lanius 1.133 }
1140    
1141 vapier 1.283 # @FUNCTION: domenu
1142     # @USAGE: <menus>
1143     # @DESCRIPTION:
1144     # Install the list of .desktop menu files into the appropriate directory
1145     # (/usr/share/applications).
1146 lanius 1.133 domenu() {
1147 vapier 1.271 (
1148     # wrap the env here so that the 'insinto' call
1149     # doesn't corrupt the env of the caller
1150     local i j ret=0
1151 lanius 1.133 insinto /usr/share/applications
1152 vapier 1.167 for i in "$@" ; do
1153     if [[ -f ${i} ]] ; then
1154     doins "${i}"
1155 vapier 1.271 ((ret+=$?))
1156 vapier 1.167 elif [[ -d ${i} ]] ; then
1157     for j in "${i}"/*.desktop ; do
1158     doins "${j}"
1159 vapier 1.271 ((ret+=$?))
1160 lanius 1.133 done
1161 vapier 1.285 else
1162     ((++ret))
1163 swegener 1.190 fi
1164 lanius 1.133 done
1165 vapier 1.271 exit ${ret}
1166     )
1167 lanius 1.133 }
1168 vapier 1.283
1169     # @FUNCTION: newmenu
1170     # @USAGE: <menu> <newname>
1171     # @DESCRIPTION:
1172     # Like all other new* functions, install the specified menu as newname.
1173 vapier 1.167 newmenu() {
1174 vapier 1.271 (
1175     # wrap the env here so that the 'insinto' call
1176     # doesn't corrupt the env of the caller
1177 vapier 1.167 insinto /usr/share/applications
1178 vapier 1.271 newins "$@"
1179     )
1180 vapier 1.167 }
1181 lanius 1.133
1182 vapier 1.283 # @FUNCTION: doicon
1183     # @USAGE: <list of icons>
1184     # @DESCRIPTION:
1185     # Install the list of icons into the icon directory (/usr/share/pixmaps).
1186     # This is useful in conjunction with creating desktop/menu files.
1187 lanius 1.133 doicon() {
1188 vapier 1.271 (
1189     # wrap the env here so that the 'insinto' call
1190     # doesn't corrupt the env of the caller
1191     local i j ret
1192 lanius 1.133 insinto /usr/share/pixmaps
1193 vapier 1.167 for i in "$@" ; do
1194     if [[ -f ${i} ]] ; then
1195     doins "${i}"
1196 vapier 1.271 ((ret+=$?))
1197 vapier 1.167 elif [[ -d ${i} ]] ; then
1198     for j in "${i}"/*.png ; do
1199     doins "${j}"
1200 vapier 1.271 ((ret+=$?))
1201 lanius 1.133 done
1202 vapier 1.285 else
1203     ((++ret))
1204 swegener 1.190 fi
1205 lanius 1.133 done
1206 vapier 1.271 exit ${ret}
1207     )
1208 lanius 1.133 }
1209 vapier 1.283
1210     # @FUNCTION: newicon
1211     # @USAGE: <icon> <newname>
1212     # @DESCRIPTION:
1213     # Like all other new* functions, install the specified icon as newname.
1214 vapier 1.167 newicon() {
1215 vapier 1.271 (
1216     # wrap the env here so that the 'insinto' call
1217     # doesn't corrupt the env of the caller
1218 vapier 1.167 insinto /usr/share/pixmaps
1219 vapier 1.271 newins "$@"
1220     )
1221 vapier 1.167 }
1222 lanius 1.133
1223 vapier 1.70 # for internal use only (unpack_pdv and unpack_makeself)
1224     find_unpackable_file() {
1225 vapier 1.196 local src=$1
1226     if [[ -z ${src} ]] ; then
1227     src=${DISTDIR}/${A}
1228 vapier 1.50 else
1229 vapier 1.196 if [[ -e ${DISTDIR}/${src} ]] ; then
1230     src=${DISTDIR}/${src}
1231     elif [[ -e ${PWD}/${src} ]] ; then
1232     src=${PWD}/${src}
1233     elif [[ -e ${src} ]] ; then
1234     src=${src}
1235 vapier 1.50 fi
1236     fi
1237 vapier 1.196 [[ ! -e ${src} ]] && return 1
1238 vapier 1.70 echo "${src}"
1239     }
1240    
1241 vapier 1.283 # @FUNCTION: unpack_pdv
1242     # @USAGE: <file to unpack> <size of off_t>
1243     # @DESCRIPTION:
1244 vapier 1.70 # Unpack those pesky pdv generated files ...
1245     # They're self-unpacking programs with the binary package stuffed in
1246     # the middle of the archive. Valve seems to use it a lot ... too bad
1247     # it seems to like to segfault a lot :(. So lets take it apart ourselves.
1248 swegener 1.286 #
1249 vapier 1.283 # You have to specify the off_t size ... I have no idea how to extract that
1250     # information out of the binary executable myself. Basically you pass in
1251     # the size of the off_t type (in bytes) on the machine that built the pdv
1252     # archive.
1253 vapier 1.70 #
1254 vapier 1.283 # One way to determine this is by running the following commands:
1255 ulm 1.288 #
1256     # @CODE
1257     # strings <pdv archive> | grep lseek
1258     # strace -elseek <pdv archive>
1259     # @CODE
1260     #
1261 vapier 1.283 # Basically look for the first lseek command (we do the strings/grep because
1262     # sometimes the function call is _llseek or something) and steal the 2nd
1263     # parameter. Here is an example:
1264 ulm 1.288 #
1265     # @CODE
1266     # vapier@vapier 0 pdv_unpack # strings hldsupdatetool.bin | grep lseek
1267     # lseek
1268     # vapier@vapier 0 pdv_unpack # strace -elseek ./hldsupdatetool.bin
1269     # lseek(3, -4, SEEK_END) = 2981250
1270     # @CODE
1271     #
1272 vapier 1.283 # Thus we would pass in the value of '4' as the second parameter.
1273 vapier 1.70 unpack_pdv() {
1274 vapier 1.271 local src=$(find_unpackable_file "$1")
1275 vapier 1.196 local sizeoff_t=$2
1276 vapier 1.70
1277 vapier 1.196 [[ -z ${src} ]] && die "Could not locate source for '$1'"
1278     [[ -z ${sizeoff_t} ]] && die "No idea what off_t size was used for this pdv :("
1279 vapier 1.70
1280 vapier 1.212 local shrtsrc=$(basename "${src}")
1281 vapier 1.70 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1282 vapier 1.271 local metaskip=$(tail -c ${sizeoff_t} "${src}" | hexdump -e \"%i\")
1283     local tailskip=$(tail -c $((${sizeoff_t}*2)) "${src}" | head -c ${sizeoff_t} | hexdump -e \"%i\")
1284 vapier 1.70
1285     # grab metadata for debug reasons
1286 vapier 1.271 local metafile=$(emktemp)
1287     tail -c +$((${metaskip}+1)) "${src}" > "${metafile}"
1288 vapier 1.70
1289     # rip out the final file name from the metadata
1290 vapier 1.271 local datafile=$(tail -c +$((${metaskip}+1)) "${src}" | strings | head -n 1)
1291     datafile=$(basename "${datafile}")
1292 vapier 1.70
1293 vapier 1.71 # now lets uncompress/untar the file if need be
1294 vapier 1.271 local tmpfile=$(emktemp)
1295 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null | head -c 512 > ${tmpfile}
1296 vapier 1.71
1297 vapier 1.271 local iscompressed=$(file -b "${tmpfile}")
1298     if [[ ${iscompressed:0:8} == "compress" ]] ; then
1299 vapier 1.71 iscompressed=1
1300     mv ${tmpfile}{,.Z}
1301     gunzip ${tmpfile}
1302     else
1303     iscompressed=0
1304     fi
1305 vapier 1.271 local istar=$(file -b "${tmpfile}")
1306     if [[ ${istar:0:9} == "POSIX tar" ]] ; then
1307 vapier 1.71 istar=1
1308     else
1309     istar=0
1310     fi
1311    
1312     #for some reason gzip dies with this ... dd cant provide buffer fast enough ?
1313     #dd if=${src} ibs=${metaskip} count=1 \
1314     # | dd ibs=${tailskip} skip=1 \
1315     # | gzip -dc \
1316     # > ${datafile}
1317     if [ ${iscompressed} -eq 1 ] ; then
1318     if [ ${istar} -eq 1 ] ; then
1319     tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1320     | head -c $((${metaskip}-${tailskip})) \
1321     | tar -xzf -
1322     else
1323 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1324     | head -c $((${metaskip}-${tailskip})) \
1325     | gzip -dc \
1326     > ${datafile}
1327 vapier 1.71 fi
1328     else
1329     if [ ${istar} -eq 1 ] ; then
1330     tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1331     | head -c $((${metaskip}-${tailskip})) \
1332 vapier 1.73 | tar --no-same-owner -xf -
1333 vapier 1.71 else
1334 vapier 1.70 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1335     | head -c $((${metaskip}-${tailskip})) \
1336     > ${datafile}
1337 vapier 1.71 fi
1338     fi
1339     true
1340     #[ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1341 vapier 1.70 #assert "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1342     }
1343    
1344 vapier 1.283 # @FUNCTION: unpack_makeself
1345     # @USAGE: [file to unpack] [offset] [tail|dd]
1346     # @DESCRIPTION:
1347 vapier 1.70 # Unpack those pesky makeself generated files ...
1348     # They're shell scripts with the binary package tagged onto
1349     # the end of the archive. Loki utilized the format as does
1350     # many other game companies.
1351 swegener 1.286 #
1352 vapier 1.283 # If the file is not specified, then ${A} is used. If the
1353     # offset is not specified then we will attempt to extract
1354     # the proper offset from the script itself.
1355 vapier 1.70 unpack_makeself() {
1356 vapier 1.217 local src_input=${1:-${A}}
1357     local src=$(find_unpackable_file "${src_input}")
1358 vapier 1.196 local skip=$2
1359     local exe=$3
1360    
1361 vapier 1.217 [[ -z ${src} ]] && die "Could not locate source for '${src_input}'"
1362 vapier 1.50
1363 vapier 1.196 local shrtsrc=$(basename "${src}")
1364 vapier 1.41 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1365 vapier 1.212 if [[ -z ${skip} ]] ; then
1366 mr_bones_ 1.343 local ver=$(grep -m1 -a '#.*Makeself' "${src}" | awk '{print $NF}')
1367 vapier 1.41 local skip=0
1368 vapier 1.112 exe=tail
1369 vapier 1.41 case ${ver} in
1370 wolf31o2 1.240 1.5.*|1.6.0-nv) # tested 1.5.{3,4,5} ... guessing 1.5.x series is same
1371 vapier 1.112 skip=$(grep -a ^skip= "${src}" | cut -d= -f2)
1372 vapier 1.41 ;;
1373     2.0|2.0.1)
1374 vapier 1.112 skip=$(grep -a ^$'\t'tail "${src}" | awk '{print $2}' | cut -b2-)
1375 vapier 1.41 ;;
1376 wolf31o2 1.48 2.1.1)
1377 vapier 1.112 skip=$(grep -a ^offset= "${src}" | awk '{print $2}' | cut -b2-)
1378 vapier 1.344 (( skip++ ))
1379 wolf31o2 1.48 ;;
1380 vapier 1.49 2.1.2)
1381 vapier 1.112 skip=$(grep -a ^offset= "${src}" | awk '{print $3}' | head -n 1)
1382 vapier 1.344 (( skip++ ))
1383 vapier 1.49 ;;
1384 wolf31o2 1.48 2.1.3)
1385 vapier 1.112 skip=`grep -a ^offset= "${src}" | awk '{print $3}'`
1386 vapier 1.344 (( skip++ ))
1387 vapier 1.41 ;;
1388 wolf31o2 1.211 2.1.4|2.1.5)
1389 vapier 1.112 skip=$(grep -a offset=.*head.*wc "${src}" | awk '{print $3}' | head -n 1)
1390     skip=$(head -n ${skip} "${src}" | wc -c)
1391     exe="dd"
1392     ;;
1393 vapier 1.41 *)
1394     eerror "I'm sorry, but I was unable to support the Makeself file."
1395     eerror "The version I detected was '${ver}'."
1396     eerror "Please file a bug about the file ${shrtsrc} at"
1397     eerror "http://bugs.gentoo.org/ so that support can be added."
1398     die "makeself version '${ver}' not supported"
1399     ;;
1400     esac
1401     debug-print "Detected Makeself version ${ver} ... using ${skip} as offset"
1402     fi
1403 vapier 1.112 case ${exe} in
1404     tail) exe="tail -n +${skip} '${src}'";;
1405 vapier 1.344 dd) exe="dd ibs=${skip} skip=1 if='${src}'";;
1406 vapier 1.112 *) die "makeself cant handle exe '${exe}'"
1407     esac
1408 vapier 1.41
1409 vapier 1.68 # lets grab the first few bytes of the file to figure out what kind of archive it is
1410 vapier 1.356 local filetype tmpfile=$(emktemp)
1411 vapier 1.112 eval ${exe} 2>/dev/null | head -c 512 > "${tmpfile}"
1412 vapier 1.356 filetype=$(file -b "${tmpfile}") || die
1413 vapier 1.68 case ${filetype} in
1414 vapier 1.257 *tar\ archive*)
1415 vapier 1.112 eval ${exe} | tar --no-same-owner -xf -
1416 vapier 1.68 ;;
1417     bzip2*)
1418 vapier 1.112 eval ${exe} | bzip2 -dc | tar --no-same-owner -xf -
1419 mr_bones_ 1.69 ;;
1420 vapier 1.68 gzip*)
1421 vapier 1.112 eval ${exe} | tar --no-same-owner -xzf -
1422 vapier 1.68 ;;
1423 vapier 1.93 compress*)
1424 vapier 1.112 eval ${exe} | gunzip | tar --no-same-owner -xf -
1425 vapier 1.93 ;;
1426 vapier 1.68 *)
1427 vapier 1.93 eerror "Unknown filetype \"${filetype}\" ?"
1428 vapier 1.68 false
1429     ;;
1430     esac
1431     assert "failure unpacking (${filetype}) makeself ${shrtsrc} ('${ver}' +${skip})"
1432 wolf31o2 1.56 }
1433    
1434 vapier 1.283 # @FUNCTION: check_license
1435     # @USAGE: [license]
1436     # @DESCRIPTION:
1437     # Display a license for user to accept. If no license is
1438     # specified, then ${LICENSE} is used.
1439 wolf31o2 1.56 check_license() {
1440 vapier 1.60 local lic=$1
1441     if [ -z "${lic}" ] ; then
1442     lic="${PORTDIR}/licenses/${LICENSE}"
1443 wolf31o2 1.56 else
1444 wolf31o2 1.199 if [ -e "${PORTDIR}/licenses/${lic}" ] ; then
1445     lic="${PORTDIR}/licenses/${lic}"
1446     elif [ -e "${PWD}/${lic}" ] ; then
1447     lic="${PWD}/${lic}"
1448     elif [ -e "${lic}" ] ; then
1449     lic="${lic}"
1450 wolf31o2 1.56 fi
1451     fi
1452 vapier 1.64 local l="`basename ${lic}`"
1453 wolf31o2 1.56
1454 vapier 1.60 # here is where we check for the licenses the user already
1455     # accepted ... if we don't find a match, we make the user accept
1456     local alic
1457 vapier 1.322 eshopts_push -o noglob # so that bash doesn't expand "*"
1458 wolf31o2 1.104 for alic in ${ACCEPT_LICENSE} ; do
1459 wolf31o2 1.255 if [[ ${alic} == ${l} ]]; then
1460 vapier 1.322 eshopts_pop
1461 wolf31o2 1.106 return 0
1462     fi
1463 vapier 1.60 done
1464 vapier 1.322 eshopts_pop
1465 zmedico 1.324 [ ! -f "${lic}" ] && die "Could not find requested license ${lic}"
1466 vapier 1.60
1467 vapier 1.271 local licmsg=$(emktemp)
1468     cat <<-EOF > ${licmsg}
1469     **********************************************************
1470     The following license outlines the terms of use of this
1471     package. You MUST accept this license for installation to
1472     continue. When you are done viewing, hit 'q'. If you
1473     CTRL+C out of this, the install will not run!
1474     **********************************************************
1475 swegener 1.286
1476 vapier 1.271 EOF
1477 vapier 1.60 cat ${lic} >> ${licmsg}
1478     ${PAGER:-less} ${licmsg} || die "Could not execute pager (${PAGER}) to accept ${lic}"
1479 vapier 1.64 einfon "Do you accept the terms of this license (${l})? [yes/no] "
1480 vapier 1.60 read alic
1481     case ${alic} in
1482     yes|Yes|y|Y)
1483     return 0
1484     ;;
1485     *)
1486     echo;echo;echo
1487     eerror "You MUST accept the license to continue! Exiting!"
1488     die "Failed to accept license"
1489     ;;
1490     esac
1491 vapier 1.23 }
1492 vapier 1.75
1493 vapier 1.283 # @FUNCTION: cdrom_get_cds
1494     # @USAGE: <file on cd1> [file on cd2] [file on cd3] [...]
1495     # @DESCRIPTION:
1496 vapier 1.75 # Aquire cd(s) for those lovely cd-based emerges. Yes, this violates
1497     # the whole 'non-interactive' policy, but damnit I want CD support !
1498 swegener 1.286 #
1499 vapier 1.283 # With these cdrom functions we handle all the user interaction and
1500     # standardize everything. All you have to do is call cdrom_get_cds()
1501 vapier 1.75 # and when the function returns, you can assume that the cd has been
1502     # found at CDROM_ROOT.
1503 swegener 1.286 #
1504 vapier 1.283 # The function will attempt to locate a cd based upon a file that is on
1505     # the cd. The more files you give this function, the more cds
1506     # the cdrom functions will handle.
1507 swegener 1.286 #
1508 vapier 1.283 # Normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2',
1509     # etc... If you want to give the cds better names, then just export
1510 vapier 1.243 # the appropriate CDROM_NAME variable before calling cdrom_get_cds().
1511 vapier 1.283 # Use CDROM_NAME for one cd, or CDROM_NAME_# for multiple cds. You can
1512     # also use the CDROM_NAME_SET bash array.
1513 swegener 1.286 #
1514 vapier 1.283 # For those multi cd ebuilds, see the cdrom_load_next_cd() function.
1515 vapier 1.75 cdrom_get_cds() {
1516     # first we figure out how many cds we're dealing with by
1517     # the # of files they gave us
1518     local cdcnt=0
1519     local f=
1520     for f in "$@" ; do
1521 vapier 1.214 ((++cdcnt))
1522 vapier 1.75 export CDROM_CHECK_${cdcnt}="$f"
1523     done
1524     export CDROM_TOTAL_CDS=${cdcnt}
1525     export CDROM_CURRENT_CD=1
1526    
1527     # now we see if the user gave use CD_ROOT ...
1528     # if they did, let's just believe them that it's correct
1529 vapier 1.215 if [[ -n ${CD_ROOT}${CD_ROOT_1} ]] ; then
1530 vapier 1.75 local var=
1531     cdcnt=0
1532 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1533 vapier 1.214 ((++cdcnt))
1534 vapier 1.75 var="CD_ROOT_${cdcnt}"
1535 vapier 1.215 [[ -z ${!var} ]] && var="CD_ROOT"
1536 vapier 1.131 if [[ -z ${!var} ]] ; then
1537 vapier 1.75 eerror "You must either use just the CD_ROOT"
1538     eerror "or specify ALL the CD_ROOT_X variables."
1539     eerror "In this case, you will need ${CDROM_TOTAL_CDS} CD_ROOT_X variables."
1540     die "could not locate CD_ROOT_${cdcnt}"
1541     fi
1542     done
1543 vapier 1.215 export CDROM_ROOT=${CD_ROOT_1:-${CD_ROOT}}
1544 vapier 1.75 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1545 vapier 1.215 export CDROM_SET=-1
1546     for f in ${CDROM_CHECK_1//:/ } ; do
1547     ((++CDROM_SET))
1548 cardoe 1.346 [[ -e ${CDROM_ROOT}/${f} ]] && break
1549 vapier 1.215 done
1550     export CDROM_MATCH=${f}
1551 vapier 1.75 return
1552     fi
1553    
1554 vapier 1.215 # User didn't help us out so lets make sure they know they can
1555     # simplify the whole process ...
1556 vapier 1.131 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1557 vapier 1.215 einfo "This ebuild will need the ${CDROM_NAME:-cdrom for ${PN}}"
1558 vapier 1.75 echo
1559     einfo "If you do not have the CD, but have the data files"
1560     einfo "mounted somewhere on your filesystem, just export"
1561     einfo "the variable CD_ROOT so that it points to the"
1562     einfo "directory containing the files."
1563     echo
1564 vapier 1.132 einfo "For example:"
1565     einfo "export CD_ROOT=/mnt/cdrom"
1566     echo
1567 vapier 1.75 else
1568 vapier 1.243 if [[ -n ${CDROM_NAME_SET} ]] ; then
1569     # Translate the CDROM_NAME_SET array into CDROM_NAME_#
1570     cdcnt=0
1571     while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1572     ((++cdcnt))
1573     export CDROM_NAME_${cdcnt}="${CDROM_NAME_SET[$((${cdcnt}-1))]}"
1574     done
1575     fi
1576    
1577 vapier 1.75 einfo "This package will need access to ${CDROM_TOTAL_CDS} cds."
1578     cdcnt=0
1579 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1580 vapier 1.214 ((++cdcnt))
1581 vapier 1.75 var="CDROM_NAME_${cdcnt}"
1582 vapier 1.131 [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}"
1583 vapier 1.75 done
1584     echo
1585     einfo "If you do not have the CDs, but have the data files"
1586     einfo "mounted somewhere on your filesystem, just export"
1587     einfo "the following variables so they point to the right place:"
1588 nyhm 1.347 einfon ""
1589 vapier 1.75 cdcnt=0
1590 vapier 1.131 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1591 vapier 1.214 ((++cdcnt))
1592 vapier 1.75 echo -n " CD_ROOT_${cdcnt}"
1593     done
1594     echo
1595     einfo "Or, if you have all the files in the same place, or"
1596     einfo "you only have one cdrom, you can export CD_ROOT"
1597     einfo "and that place will be used as the same data source"
1598     einfo "for all the CDs."
1599     echo
1600 vapier 1.132 einfo "For example:"
1601     einfo "export CD_ROOT_1=/mnt/cdrom"
1602     echo
1603 vapier 1.75 fi
1604 vapier 1.215
1605 vapier 1.214 export CDROM_SET=""
1606 vapier 1.75 export CDROM_CURRENT_CD=0
1607     cdrom_load_next_cd
1608     }
1609    
1610 vapier 1.283 # @FUNCTION: cdrom_load_next_cd
1611     # @DESCRIPTION:
1612     # Some packages are so big they come on multiple CDs. When you're done reading
1613     # files off a CD and want access to the next one, just call this function.
1614     # Again, all the messy details of user interaction are taken care of for you.
1615     # Once this returns, just read the variable CDROM_ROOT for the location of the
1616     # mounted CD. Note that you can only go forward in the CD list, so make sure
1617     # you only call this function when you're done using the current CD.
1618 vapier 1.75 cdrom_load_next_cd() {
1619 vapier 1.215 local var
1620     ((++CDROM_CURRENT_CD))
1621 vapier 1.79
1622 vapier 1.75 unset CDROM_ROOT
1623 vapier 1.215 var=CD_ROOT_${CDROM_CURRENT_CD}
1624     [[ -z ${!var} ]] && var="CD_ROOT"
1625 vapier 1.131 if [[ -z ${!var} ]] ; then
1626 vapier 1.75 var="CDROM_CHECK_${CDROM_CURRENT_CD}"
1627 vapier 1.215 _cdrom_locate_file_on_cd ${!var}
1628 vapier 1.75 else
1629 vapier 1.131 export CDROM_ROOT=${!var}
1630 vapier 1.75 fi
1631    
1632     einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1633     }
1634    
1635     # this is used internally by the cdrom_get_cds() and cdrom_load_next_cd()
1636     # functions. this should *never* be called from an ebuild.
1637     # all it does is try to locate a give file on a cd ... if the cd isn't
1638     # found, then a message asking for the user to insert the cdrom will be
1639     # displayed and we'll hang out here until:
1640     # (1) the file is found on a mounted cdrom
1641     # (2) the user hits CTRL+C
1642 vapier 1.215 _cdrom_locate_file_on_cd() {
1643 vapier 1.214 local mline=""
1644 wolf31o2 1.296 local showedmsg=0 showjolietmsg=0
1645 vapier 1.214
1646 vapier 1.131 while [[ -z ${CDROM_ROOT} ]] ; do
1647 vapier 1.214 local i=0
1648     local -a cdset=(${*//:/ })
1649     if [[ -n ${CDROM_SET} ]] ; then
1650     cdset=(${cdset[${CDROM_SET}]})
1651     fi
1652    
1653     while [[ -n ${cdset[${i}]} ]] ; do
1654     local dir=$(dirname ${cdset[${i}]})
1655     local file=$(basename ${cdset[${i}]})
1656    
1657 uberlord 1.259 local point= node= fs= foo=
1658     while read point node fs foo ; do
1659 nyhm 1.281 [[ " cd9660 iso9660 udf " != *" ${fs} "* ]] && \
1660 uberlord 1.264 ! [[ ${fs} == "subfs" && ",${opts}," == *",fs=cdfss,"* ]] \
1661     && continue
1662 uberlord 1.259 point=${point//\040/ }
1663 vapier 1.292 [[ ! -d ${point}/${dir} ]] && continue
1664 uberlord 1.259 [[ -z $(find "${point}/${dir}" -maxdepth 1 -iname "${file}") ]] && continue
1665     export CDROM_ROOT=${point}
1666     export CDROM_SET=${i}
1667     export CDROM_MATCH=${cdset[${i}]}
1668     return
1669 kanaka 1.262 done <<< "$(get_mounts)"
1670 vapier 1.214
1671     ((++i))
1672 vapier 1.75 done
1673    
1674 vapier 1.214 echo
1675     if [[ ${showedmsg} -eq 0 ]] ; then
1676     if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1677     if [[ -z ${CDROM_NAME} ]] ; then
1678     einfo "Please insert+mount the cdrom for ${PN} now !"
1679     else
1680     einfo "Please insert+mount the ${CDROM_NAME} cdrom now !"
1681     fi
1682     else
1683     if [[ -z ${CDROM_NAME_1} ]] ; then
1684     einfo "Please insert+mount cd #${CDROM_CURRENT_CD} for ${PN} now !"
1685 vapier 1.75 else
1686 vapier 1.214 local var="CDROM_NAME_${CDROM_CURRENT_CD}"
1687     einfo "Please insert+mount the ${!var} cdrom now !"
1688 vapier 1.75 fi
1689     fi
1690 vapier 1.214 showedmsg=1
1691 vapier 1.75 fi
1692 vapier 1.214 einfo "Press return to scan for the cd again"
1693     einfo "or hit CTRL+C to abort the emerge."
1694     echo
1695 wolf31o2 1.296 if [[ ${showjolietmsg} -eq 0 ]] ; then
1696     showjolietmsg=1
1697     else
1698     ewarn "If you are having trouble with the detection"
1699     ewarn "of your CD, it is possible that you do not have"
1700     ewarn "Joliet support enabled in your kernel. Please"
1701     ewarn "check that CONFIG_JOLIET is enabled in your kernel."
1702     ebeep 5
1703     fi
1704 vapier 1.222 read || die "something is screwed with your system"
1705 vapier 1.75 done
1706     }
1707 vapier 1.92
1708 vapier 1.287 # @FUNCTION: strip-linguas
1709     # @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1710     # @DESCRIPTION:
1711 mr_bones_ 1.100 # Make sure that LINGUAS only contains languages that
1712 vapier 1.287 # a package can support. The first form allows you to
1713     # specify a list of LINGUAS. The -i builds a list of po
1714     # files found in all the directories and uses the
1715     # intersection of the lists. The -u builds a list of po
1716     # files found in all the directories and uses the union
1717     # of the lists.
1718 vapier 1.92 strip-linguas() {
1719 vapier 1.242 local ls newls nols
1720 vapier 1.154 if [[ $1 == "-i" ]] || [[ $1 == "-u" ]] ; then
1721     local op=$1; shift
1722 vapier 1.315 ls=$(find "$1" -name '*.po' -exec basename {} .po ';'); shift
1723 vapier 1.92 local d f
1724     for d in "$@" ; do
1725 vapier 1.154 if [[ ${op} == "-u" ]] ; then
1726     newls=${ls}
1727 vapier 1.92 else
1728     newls=""
1729     fi
1730 vapier 1.315 for f in $(find "$d" -name '*.po' -exec basename {} .po ';') ; do
1731 vapier 1.154 if [[ ${op} == "-i" ]] ; then
1732 ssuominen 1.358 has ${f} ${ls} && newls="${newls} ${f}"
1733 vapier 1.92 else
1734 ssuominen 1.358 has ${f} ${ls} || newls="${newls} ${f}"
1735 vapier 1.92 fi
1736     done
1737 vapier 1.154 ls=${newls}
1738 vapier 1.92 done
1739     else
1740 vapier 1.236 ls="$@"
1741 vapier 1.92 fi
1742    
1743 vapier 1.242 nols=""
1744 vapier 1.92 newls=""
1745     for f in ${LINGUAS} ; do
1746 ssuominen 1.358 if has ${f} ${ls} ; then
1747 vapier 1.120 newls="${newls} ${f}"
1748 vapier 1.92 else
1749 vapier 1.242 nols="${nols} ${f}"
1750 vapier 1.92 fi
1751     done
1752 vapier 1.244 [[ -n ${nols} ]] \
1753 vapier 1.316 && ewarn "Sorry, but ${PN} does not support the LINGUAS:" ${nols}
1754 vapier 1.237 export LINGUAS=${newls:1}
1755 vapier 1.92 }
1756 iggy 1.110
1757 vapier 1.283 # @FUNCTION: preserve_old_lib
1758     # @USAGE: <libs to preserve> [more libs]
1759     # @DESCRIPTION:
1760     # These functions are useful when a lib in your package changes ABI SONAME.
1761     # An example might be from libogg.so.0 to libogg.so.1. Removing libogg.so.0
1762 eradicator 1.111 # would break packages that link against it. Most people get around this
1763     # by using the portage SLOT mechanism, but that is not always a relevant
1764 vapier 1.283 # solution, so instead you can call this from pkg_preinst. See also the
1765     # preserve_old_lib_notify function.
1766 eradicator 1.111 preserve_old_lib() {
1767 vapier 1.268 if [[ ${EBUILD_PHASE} != "preinst" ]] ; then
1768 vapier 1.267 eerror "preserve_old_lib() must be called from pkg_preinst() only"
1769 vapier 1.276 die "Invalid preserve_old_lib() usage"
1770 vapier 1.267 fi
1771     [[ -z $1 ]] && die "Usage: preserve_old_lib <library to preserve> [more libraries to preserve]"
1772    
1773 vapier 1.297 # let portage worry about it
1774     has preserve-libs ${FEATURES} && return 0
1775    
1776 vapier 1.267 local lib dir
1777     for lib in "$@" ; do
1778     [[ -e ${ROOT}/${lib} ]] || continue
1779     dir=${lib%/*}
1780     dodir ${dir} || die "dodir ${dir} failed"
1781     cp "${ROOT}"/${lib} "${D}"/${lib} || die "cp ${lib} failed"
1782     touch "${D}"/${lib}
1783     done
1784 eradicator 1.111 }
1785    
1786 vapier 1.283 # @FUNCTION: preserve_old_lib_notify
1787     # @USAGE: <libs to notify> [more libs]
1788     # @DESCRIPTION:
1789     # Spit helpful messages about the libraries preserved by preserve_old_lib.
1790 eradicator 1.111 preserve_old_lib_notify() {
1791 vapier 1.268 if [[ ${EBUILD_PHASE} != "postinst" ]] ; then
1792 vapier 1.267 eerror "preserve_old_lib_notify() must be called from pkg_postinst() only"
1793 vapier 1.276 die "Invalid preserve_old_lib_notify() usage"
1794 vapier 1.267 fi
1795    
1796 vapier 1.297 # let portage worry about it
1797     has preserve-libs ${FEATURES} && return 0
1798    
1799 vapier 1.267 local lib notice=0
1800     for lib in "$@" ; do
1801     [[ -e ${ROOT}/${lib} ]] || continue
1802     if [[ ${notice} -eq 0 ]] ; then
1803     notice=1
1804     ewarn "Old versions of installed libraries were detected on your system."
1805     ewarn "In order to avoid breaking packages that depend on these old libs,"
1806     ewarn "the libraries are not being removed. You need to run revdep-rebuild"
1807     ewarn "in order to remove these old dependencies. If you do not have this"
1808     ewarn "helper program, simply emerge the 'gentoolkit' package."
1809     ewarn
1810     fi
1811 vapier 1.355 # temp hack for #348634 #357225
1812     [[ ${PN} == "mpfr" ]] && lib=${lib##*/}
1813 vapier 1.352 ewarn " # revdep-rebuild --library '${lib}'"
1814 vapier 1.267 done
1815 vapier 1.291 if [[ ${notice} -eq 1 ]] ; then
1816     ewarn
1817     ewarn "Once you've finished running revdep-rebuild, it should be safe to"
1818 vapier 1.300 ewarn "delete the old libraries. Here is a copy & paste for the lazy:"
1819     for lib in "$@" ; do
1820     ewarn " # rm '${lib}'"
1821     done
1822 vapier 1.291 fi
1823 eradicator 1.111 }
1824 vapier 1.125
1825 vapier 1.283 # @FUNCTION: built_with_use
1826     # @USAGE: [--hidden] [--missing <action>] [-a|-o] <DEPEND ATOM> <List of USE flags>
1827     # @DESCRIPTION:
1828 betelgeuse 1.329 #
1829     # Deprecated: Use EAPI 2 use deps in DEPEND|RDEPEND and with has_version calls.
1830     #
1831 vapier 1.283 # A temporary hack until portage properly supports DEPENDing on USE
1832     # flags being enabled in packages. This will check to see if the specified
1833     # DEPEND atom was built with the specified list of USE flags. The
1834     # --missing option controls the behavior if called on a package that does
1835     # not actually support the defined USE flags (aka listed in IUSE).
1836     # The default is to abort (call die). The -a and -o flags control
1837     # the requirements of the USE flags. They correspond to "and" and "or"
1838     # logic. So the -a flag means all listed USE flags must be enabled
1839 opfer 1.302 # while the -o flag means at least one of the listed IUSE flags must be
1840 vapier 1.283 # enabled. The --hidden option is really for internal use only as it
1841     # means the USE flag we're checking is hidden expanded, so it won't be found
1842     # in IUSE like normal USE flags.
1843 swegener 1.286 #
1844 vapier 1.283 # Remember that this function isn't terribly intelligent so order of optional
1845     # flags matter.
1846 vapier 1.125 built_with_use() {
1847 vapier 1.275 local hidden="no"
1848     if [[ $1 == "--hidden" ]] ; then
1849     hidden="yes"
1850     shift
1851     fi
1852    
1853 vapier 1.269 local missing_action="die"
1854     if [[ $1 == "--missing" ]] ; then
1855     missing_action=$2
1856     shift ; shift
1857     case ${missing_action} in
1858     true|false|die) ;;
1859     *) die "unknown action '${missing_action}'";;
1860     esac
1861     fi
1862    
1863 vapier 1.130 local opt=$1
1864     [[ ${opt:0:1} = "-" ]] && shift || opt="-a"
1865    
1866     local PKG=$(best_version $1)
1867 vapier 1.247 [[ -z ${PKG} ]] && die "Unable to resolve $1 to an installed package"
1868 vapier 1.130 shift
1869    
1870 vapier 1.213 local USEFILE=${ROOT}/var/db/pkg/${PKG}/USE
1871 vapier 1.249 local IUSEFILE=${ROOT}/var/db/pkg/${PKG}/IUSE
1872 vapier 1.213
1873 cardoe 1.273 # if the IUSE file doesn't exist, the read will error out, we need to handle
1874     # this gracefully
1875 vapier 1.275 if [[ ! -e ${USEFILE} ]] || [[ ! -e ${IUSEFILE} && ${hidden} == "no" ]] ; then
1876 cardoe 1.273 case ${missing_action} in
1877     true) return 0;;
1878     false) return 1;;
1879     die) die "Unable to determine what USE flags $PKG was built with";;
1880     esac
1881     fi
1882    
1883 vapier 1.275 if [[ ${hidden} == "no" ]] ; then
1884 zmedico 1.301 local IUSE_BUILT=( $(<"${IUSEFILE}") )
1885 vapier 1.275 # Don't check USE_EXPAND #147237
1886     local expand
1887     for expand in $(echo ${USE_EXPAND} | tr '[:upper:]' '[:lower:]') ; do
1888     if [[ $1 == ${expand}_* ]] ; then
1889     expand=""
1890     break
1891     fi
1892     done
1893     if [[ -n ${expand} ]] ; then
1894 zmedico 1.301 if ! has $1 ${IUSE_BUILT[@]#[-+]} ; then
1895 vapier 1.275 case ${missing_action} in
1896     true) return 0;;
1897     false) return 1;;
1898     die) die "$PKG does not actually support the $1 USE flag!";;
1899     esac
1900     fi
1901 vapier 1.269 fi
1902 vapier 1.250 fi
1903 vapier 1.249
1904 vapier 1.125 local USE_BUILT=$(<${USEFILE})
1905 vapier 1.130 while [[ $# -gt 0 ]] ; do
1906     if [[ ${opt} = "-o" ]] ; then
1907     has $1 ${USE_BUILT} && return 0
1908     else
1909     has $1 ${USE_BUILT} || return 1
1910     fi
1911 vapier 1.125 shift
1912     done
1913 vapier 1.130 [[ ${opt} = "-a" ]]
1914 vapier 1.125 }
1915 vapier 1.126
1916 vapier 1.289 # @FUNCTION: epunt_cxx
1917 vapier 1.283 # @USAGE: [dir to scan]
1918     # @DESCRIPTION:
1919     # Many configure scripts wrongly bail when a C++ compiler could not be
1920     # detected. If dir is not specified, then it defaults to ${S}.
1921     #
1922     # http://bugs.gentoo.org/73450
1923 vapier 1.126 epunt_cxx() {
1924 vapier 1.127 local dir=$1
1925     [[ -z ${dir} ]] && dir=${S}
1926     ebegin "Removing useless C++ checks"
1927     local f
1928 vapier 1.294 find "${dir}" -name configure | while read f ; do
1929     patch --no-backup-if-mismatch -p0 "${f}" "${PORTDIR}/eclass/ELT-patches/nocxx/nocxx.patch" > /dev/null
1930 vapier 1.127 done
1931     eend 0
1932 vapier 1.126 }
1933 ka0ttic 1.143
1934 vapier 1.283 # @FUNCTION: make_wrapper
1935 wolf31o2 1.295 # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
1936 vapier 1.283 # @DESCRIPTION:
1937     # Create a shell wrapper script named wrapper in installpath
1938     # (defaults to the bindir) to execute target (default of wrapper) by
1939     # first optionally setting LD_LIBRARY_PATH to the colon-delimited
1940     # libpaths followed by optionally changing directory to chdir.
1941 wolf31o2 1.160 make_wrapper() {
1942 wolf31o2 1.164 local wrapper=$1 bin=$2 chdir=$3 libdir=$4 path=$5
1943 wolf31o2 1.160 local tmpwrapper=$(emktemp)
1944 vapier 1.202 # We don't want to quote ${bin} so that people can pass complex
1945     # things as $bin ... "./someprog --args"
1946 wolf31o2 1.160 cat << EOF > "${tmpwrapper}"
1947     #!/bin/sh
1948 vapier 1.201 cd "${chdir:-.}"
1949 vapier 1.210 if [ -n "${libdir}" ] ; then
1950     if [ "\${LD_LIBRARY_PATH+set}" = "set" ] ; then
1951     export LD_LIBRARY_PATH="\${LD_LIBRARY_PATH}:${libdir}"
1952     else
1953     export LD_LIBRARY_PATH="${libdir}"
1954     fi
1955 vapier 1.201 fi
1956 vapier 1.202 exec ${bin} "\$@"
1957 wolf31o2 1.160 EOF
1958     chmod go+rx "${tmpwrapper}"
1959 vapier 1.201 if [[ -n ${path} ]] ; then
1960 vapier 1.283 (
1961 vapier 1.201 exeinto "${path}"
1962 wolf31o2 1.164 newexe "${tmpwrapper}" "${wrapper}"
1963 vapier 1.283 ) || die
1964 wolf31o2 1.164 else
1965 vapier 1.283 newbin "${tmpwrapper}" "${wrapper}" || die
1966 wolf31o2 1.164 fi
1967 wolf31o2 1.160 }
1968 mr_bones_ 1.311
1969 vapier 1.351 # @FUNCTION: path_exists
1970     # @USAGE: [-a|-o] <paths>
1971     # @DESCRIPTION:
1972     # Check if the specified paths exist. Works for all types of paths
1973     # (files/dirs/etc...). The -a and -o flags control the requirements
1974     # of the paths. They correspond to "and" and "or" logic. So the -a
1975     # flag means all the paths must exist while the -o flag means at least
1976     # one of the paths must exist. The default behavior is "and". If no
1977     # paths are specified, then the return value is "false".
1978     path_exists() {
1979     local opt=$1
1980     [[ ${opt} == -[ao] ]] && shift || opt="-a"
1981    
1982     # no paths -> return false
1983     # same behavior as: [[ -e "" ]]
1984     [[ $# -eq 0 ]] && return 1
1985    
1986     local p r=0
1987     for p in "$@" ; do
1988     [[ -e ${p} ]]
1989     : $(( r += $? ))
1990     done
1991    
1992     case ${opt} in
1993     -a) return $(( r != 0 )) ;;
1994     -o) return $(( r == $# )) ;;
1995     esac
1996     }

  ViewVC Help
Powered by ViewVC 1.1.20