5ccf7c2245fe547a8c0c66bf41109530f2f1be4a
[proj/portage.git] / bin / misc-functions.sh
1 #!/bin/bash
2 # Copyright 1999-2013 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 #
5 # Miscellaneous shell functions that make use of the ebuild env but don't need
6 # to be included directly in ebuild.sh.
7 #
8 # We're sourcing ebuild.sh here so that we inherit all of it's goodness,
9 # including bashrc trickery. This approach allows us to do our miscellaneous
10 # shell work withing the same env that ebuild.sh has, but without polluting
11 # ebuild.sh itself with unneeded logic and shell code.
12 #
13 # XXX hack: clear the args so ebuild.sh doesn't see them
14 MISC_FUNCTIONS_ARGS="$@"
15 shift $#
16
17 source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}/ebuild.sh"
18
19 install_symlink_html_docs() {
20 if ! ___eapi_has_prefix_variables; then
21 local ED=${D}
22 fi
23 cd "${ED}" || die "cd failed"
24 #symlink the html documentation (if DOC_SYMLINKS_DIR is set in make.conf)
25 if [ -n "${DOC_SYMLINKS_DIR}" ] ; then
26 local mydocdir docdir
27 for docdir in "${HTMLDOC_DIR:-does/not/exist}" "${PF}/html" "${PF}/HTML" "${P}/html" "${P}/HTML" ; do
28 if [ -d "usr/share/doc/${docdir}" ] ; then
29 mydocdir="/usr/share/doc/${docdir}"
30 fi
31 done
32 if [ -n "${mydocdir}" ] ; then
33 local mysympath
34 if [ -z "${SLOT}" -o "${SLOT%/*}" = "0" ] ; then
35 mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}"
36 else
37 mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}-${SLOT%/*}"
38 fi
39 einfo "Symlinking ${mysympath} to the HTML documentation"
40 dodir "${DOC_SYMLINKS_DIR}/${CATEGORY}"
41 dosym "${mydocdir}" "${mysympath}"
42 fi
43 fi
44 }
45
46 # replacement for "readlink -f" or "realpath"
47 READLINK_F_WORKS=""
48 canonicalize() {
49 if [[ -z ${READLINK_F_WORKS} ]] ; then
50 if [[ $(readlink -f -- /../ 2>/dev/null) == "/" ]] ; then
51 READLINK_F_WORKS=true
52 else
53 READLINK_F_WORKS=false
54 fi
55 fi
56 if ${READLINK_F_WORKS} ; then
57 readlink -f -- "$@"
58 return
59 fi
60
61 local f=$1 b n=10 wd=$(pwd)
62 while (( n-- > 0 )); do
63 while [[ ${f: -1} = / && ${#f} -gt 1 ]]; do
64 f=${f%/}
65 done
66 b=${f##*/}
67 cd "${f%"${b}"}" 2>/dev/null || break
68 if [[ ! -L ${b} ]]; then
69 f=$(pwd -P)
70 echo "${f%/}/${b}"
71 cd "${wd}"
72 return 0
73 fi
74 f=$(readlink "${b}")
75 done
76 cd "${wd}"
77 return 1
78 }
79
80 prepcompress() {
81 local -a include exclude incl_d incl_f
82 local f g i real_f real_d
83 if ! ___eapi_has_prefix_variables; then
84 local ED=${D}
85 fi
86
87 # Canonicalize path names and check for their existence.
88 real_d=$(canonicalize "${ED}")
89 for (( i = 0; i < ${#PORTAGE_DOCOMPRESS[@]}; i++ )); do
90 real_f=$(canonicalize "${ED}${PORTAGE_DOCOMPRESS[i]}")
91 f=${real_f#"${real_d}"}
92 if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
93 then
94 include[${#include[@]}]=${f:-/}
95 elif [[ ${i} -ge 3 ]]; then
96 ewarn "prepcompress:" \
97 "ignoring nonexistent path '${PORTAGE_DOCOMPRESS[i]}'"
98 fi
99 done
100 for (( i = 0; i < ${#PORTAGE_DOCOMPRESS_SKIP[@]}; i++ )); do
101 real_f=$(canonicalize "${ED}${PORTAGE_DOCOMPRESS_SKIP[i]}")
102 f=${real_f#"${real_d}"}
103 if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
104 then
105 exclude[${#exclude[@]}]=${f:-/}
106 elif [[ ${i} -ge 1 ]]; then
107 ewarn "prepcompress:" \
108 "ignoring nonexistent path '${PORTAGE_DOCOMPRESS_SKIP[i]}'"
109 fi
110 done
111
112 # Remove redundant entries from lists.
113 # For the include list, remove any entries that are:
114 # a) contained in a directory in the include or exclude lists, or
115 # b) identical with an entry in the exclude list.
116 for (( i = ${#include[@]} - 1; i >= 0; i-- )); do
117 f=${include[i]}
118 for g in "${include[@]}"; do
119 if [[ ${f} == "${g%/}"/* ]]; then
120 unset include[i]
121 continue 2
122 fi
123 done
124 for g in "${exclude[@]}"; do
125 if [[ ${f} = "${g}" || ${f} == "${g%/}"/* ]]; then
126 unset include[i]
127 continue 2
128 fi
129 done
130 done
131 # For the exclude list, remove any entries that are:
132 # a) contained in a directory in the exclude list, or
133 # b) _not_ contained in a directory in the include list.
134 for (( i = ${#exclude[@]} - 1; i >= 0; i-- )); do
135 f=${exclude[i]}
136 for g in "${exclude[@]}"; do
137 if [[ ${f} == "${g%/}"/* ]]; then
138 unset exclude[i]
139 continue 2
140 fi
141 done
142 for g in "${include[@]}"; do
143 [[ ${f} == "${g%/}"/* ]] && continue 2
144 done
145 unset exclude[i]
146 done
147
148 # Split the include list into directories and files
149 for f in "${include[@]}"; do
150 if [[ -d ${ED}${f} ]]; then
151 incl_d[${#incl_d[@]}]=${f}
152 else
153 incl_f[${#incl_f[@]}]=${f}
154 fi
155 done
156
157 # Queue up for compression.
158 # ecompress{,dir} doesn't like to be called with empty argument lists.
159 [[ ${#incl_d[@]} -gt 0 ]] && ecompressdir --limit ${PORTAGE_DOCOMPRESS_SIZE_LIMIT:-0} --queue "${incl_d[@]}"
160 [[ ${#incl_f[@]} -gt 0 ]] && ecompress --queue "${incl_f[@]/#/${ED}}"
161 [[ ${#exclude[@]} -gt 0 ]] && ecompressdir --ignore "${exclude[@]}"
162 return 0
163 }
164
165 install_qa_check() {
166 local f i qa_var x
167 if ! ___eapi_has_prefix_variables; then
168 local EPREFIX= ED=${D}
169 fi
170
171 cd "${ED}" || die "cd failed"
172
173 qa_var="QA_FLAGS_IGNORED_${ARCH/-/_}"
174 eval "[[ -n \${!qa_var} ]] && QA_FLAGS_IGNORED=(\"\${${qa_var}[@]}\")"
175 if [[ ${#QA_FLAGS_IGNORED[@]} -eq 1 ]] ; then
176 local shopts=$-
177 set -o noglob
178 QA_FLAGS_IGNORED=(${QA_FLAGS_IGNORED})
179 set +o noglob
180 set -${shopts}
181 fi
182
183 # Check for files built without respecting *FLAGS. Note that
184 # -frecord-gcc-switches must be in all *FLAGS variables, in
185 # order to avoid false positive results here.
186 # NOTE: This check must execute before prepall/prepstrip, since
187 # prepstrip strips the .GCC.command.line sections.
188 if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT} && \
189 [[ "${CFLAGS}" == *-frecord-gcc-switches* ]] && \
190 [[ "${CXXFLAGS}" == *-frecord-gcc-switches* ]] && \
191 [[ "${FFLAGS}" == *-frecord-gcc-switches* ]] && \
192 [[ "${FCFLAGS}" == *-frecord-gcc-switches* ]] ; then
193 rm -f "${T}"/scanelf-ignored-CFLAGS.log
194 for x in $(scanelf -qyRF '#k%p' -k '!.GCC.command.line' "${ED}") ; do
195 # Separate out file types that are known to support
196 # .GCC.command.line sections, using the `file` command
197 # similar to how prepstrip uses it.
198 f=$(file "${x}") || continue
199 [[ -z ${f} ]] && continue
200 if [[ ${f} == *"SB executable"* ||
201 ${f} == *"SB shared object"* ]] ; then
202 echo "${x}" >> "${T}"/scanelf-ignored-CFLAGS.log
203 fi
204 done
205
206 if [[ -f "${T}"/scanelf-ignored-CFLAGS.log ]] ; then
207
208 if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then
209 for x in "${QA_FLAGS_IGNORED[@]}" ; do
210 sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-CFLAGS.log
211 done
212 fi
213 # Filter anything under /usr/lib/debug/ in order to avoid
214 # duplicate warnings for splitdebug files.
215 sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
216 -i "${T}"/scanelf-ignored-CFLAGS.log
217 f=$(<"${T}"/scanelf-ignored-CFLAGS.log)
218 if [[ -n ${f} ]] ; then
219 __vecho -ne '\n'
220 eqawarn "${BAD}QA Notice: Files built without respecting CFLAGS have been detected${NORMAL}"
221 eqawarn " Please include the following list of files in your report:"
222 eqawarn "${f}"
223 __vecho -ne '\n'
224 sleep 1
225 else
226 rm -f "${T}"/scanelf-ignored-CFLAGS.log
227 fi
228 fi
229 fi
230
231 export STRIP_MASK
232 prepall
233 ___eapi_has_docompress && prepcompress
234 ecompressdir --dequeue
235 ecompress --dequeue
236
237 # Prefix specific checks
238 [[ ${ED} != ${D} ]] && install_qa_check_prefix
239
240 f=
241 for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do
242 [[ -d ${ED}/$x ]] && f+=" $x\n"
243 done
244 if [[ -n $f ]] ; then
245 eqawarn "QA Notice: This ebuild installs into the following deprecated directories:"
246 eqawarn
247 eqawarn "$f"
248 fi
249
250 # It's ok create these directories, but not to install into them. #493154
251 # TODO: We should add var/lib to this list.
252 f=
253 for x in var/cache var/lock var/run run ; do
254 if [[ ! -L ${ED}/${x} && -d ${ED}/${x} ]] ; then
255 if [[ -z $(find "${ED}/${x}" -prune -empty) ]] ; then
256 f+=$(cd "${ED}"; find "${x}" -printf ' %p\n')
257 fi
258 fi
259 done
260 if [[ -n ${f} ]] ; then
261 eqawarn "QA Notice: This ebuild installs into paths that should be created at runtime."
262 eqawarn " To fix, simply do not install into these directories. Instead, your package"
263 eqawarn " should create dirs on the fly at runtime as needed via init scripts/etc..."
264 eqawarn
265 eqawarn "${f}"
266 fi
267
268 set +f
269 f=
270 for x in "${ED}etc/udev/rules.d/"* "${ED}lib"*"/udev/rules.d/"* ; do
271 [[ -e ${x} ]] || continue
272 [[ ${x} == ${ED}lib/udev/rules.d/* ]] && continue
273 f+=" ${x#${ED}}\n"
274 done
275 if [[ -n $f ]] ; then
276 eqawarn "QA Notice: udev rules should be installed in /lib/udev/rules.d:"
277 eqawarn
278 eqawarn "$f"
279 fi
280
281 # Now we look for all world writable files.
282 local unsafe_files=$(find "${ED}" -type f -perm -2 | sed -e "s:^${ED}:- :")
283 if [[ -n ${unsafe_files} ]] ; then
284 __vecho "QA Security Notice: world writable file(s):"
285 __vecho "${unsafe_files}"
286 __vecho "- This may or may not be a security problem, most of the time it is one."
287 __vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly."
288 sleep 1
289 fi
290
291 if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then
292 local insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET}
293 local x
294
295 # display warnings when using stricter because we die afterwards
296 if has stricter ${FEATURES} ; then
297 unset PORTAGE_QUIET
298 fi
299
300 # Make sure we disallow insecure RUNPATH/RPATHs.
301 # 1) References to PORTAGE_BUILDDIR are banned because it's a
302 # security risk. We don't want to load files from a
303 # temporary directory.
304 # 2) If ROOT != "/", references to ROOT are banned because
305 # that directory won't exist on the target system.
306 # 3) Null paths are banned because the loader will search $PWD when
307 # it finds null paths.
308 local forbidden_dirs="${PORTAGE_BUILDDIR}"
309 if [[ -n "${ROOT}" && "${ROOT}" != "/" ]]; then
310 forbidden_dirs+=" ${ROOT}"
311 fi
312 local dir l rpath_files=$(scanelf -F '%F:%r' -qBR "${ED}")
313 f=""
314 for dir in ${forbidden_dirs}; do
315 for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do
316 f+=" ${l%%:*}\n"
317 if ! has stricter ${FEATURES}; then
318 __vecho "Auto fixing rpaths for ${l%%:*}"
319 TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null
320 fi
321 done
322 done
323
324 # Reject set*id binaries with $ORIGIN in RPATH #260331
325 x=$(
326 find "${ED}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \
327 xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN'
328 )
329
330 # Print QA notice.
331 if [[ -n ${f}${x} ]] ; then
332 __vecho -ne '\n'
333 eqawarn "QA Notice: The following files contain insecure RUNPATHs"
334 eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
335 eqawarn " with the maintaining herd of the package."
336 eqawarn "${f}${f:+${x:+\n}}${x}"
337 __vecho -ne '\n'
338 if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
339 insecure_rpath=1
340 fi
341 fi
342
343 # TEXTRELs are baaaaaaaad
344 # Allow devs to mark things as ignorable ... e.g. things that are
345 # binary-only and upstream isn't cooperating (nvidia-glx) ... we
346 # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ...
347 # the former overrides the latter ... regexes allowed ! :)
348 qa_var="QA_TEXTRELS_${ARCH/-/_}"
349 [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var}
350 [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS=""
351 export QA_TEXTRELS="${QA_TEXTRELS} lib*/modules/*.ko"
352 f=$(scanelf -qyRF '%t %p' "${ED}" | grep -v 'usr/lib/debug/')
353 if [[ -n ${f} ]] ; then
354 scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log
355 __vecho -ne '\n'
356 eqawarn "QA Notice: The following files contain runtime text relocations"
357 eqawarn " Text relocations force the dynamic linker to perform extra"
358 eqawarn " work at startup, waste system resources, and may pose a security"
359 eqawarn " risk. On some architectures, the code may not even function"
360 eqawarn " properly, if at all."
361 eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml"
362 eqawarn " Please include the following list of files in your report:"
363 eqawarn "${f}"
364 __vecho -ne '\n'
365 die_msg="${die_msg} textrels,"
366 sleep 1
367 fi
368
369 # Also, executable stacks only matter on linux (and just glibc atm ...)
370 f=""
371 case ${CTARGET:-${CHOST}} in
372 *-linux-gnu*)
373 # Check for files with executable stacks, but only on arches which
374 # are supported at the moment. Keep this list in sync with
375 # http://www.gentoo.org/proj/en/hardened/gnu-stack.xml (Arch Status)
376 case ${CTARGET:-${CHOST}} in
377 arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*)
378 # Allow devs to mark things as ignorable ... e.g. things
379 # that are binary-only and upstream isn't cooperating ...
380 # we allow ebuild authors to set QA_EXECSTACK_arch and
381 # QA_EXECSTACK ... the former overrides the latter ...
382 # regexes allowed ! :)
383
384 qa_var="QA_EXECSTACK_${ARCH/-/_}"
385 [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var}
386 [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK=""
387 qa_var="QA_WX_LOAD_${ARCH/-/_}"
388 [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var}
389 [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD=""
390 export QA_EXECSTACK="${QA_EXECSTACK} lib*/modules/*.ko"
391 export QA_WX_LOAD="${QA_WX_LOAD} lib*/modules/*.ko"
392 f=$(scanelf -qyRAF '%e %p' "${ED}" | grep -v 'usr/lib/debug/')
393 ;;
394 esac
395 ;;
396 esac
397 if [[ -n ${f} ]] ; then
398 # One more pass to help devs track down the source
399 scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log
400 __vecho -ne '\n'
401 eqawarn "QA Notice: The following files contain writable and executable sections"
402 eqawarn " Files with such sections will not work properly (or at all!) on some"
403 eqawarn " architectures/operating systems. A bug should be filed at"
404 eqawarn " http://bugs.gentoo.org/ to make sure the issue is fixed."
405 eqawarn " For more information, see http://hardened.gentoo.org/gnu-stack.xml"
406 eqawarn " Please include the following list of files in your report:"
407 eqawarn " Note: Bugs should be filed for the respective maintainers"
408 eqawarn " of the package in question and not hardened@g.o."
409 eqawarn "${f}"
410 __vecho -ne '\n'
411 die_msg="${die_msg} execstacks"
412 sleep 1
413 fi
414
415 # Check for files built without respecting LDFLAGS
416 if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && \
417 ! has binchecks ${RESTRICT} ; then
418 f=$(scanelf -qyRF '#k%p' -k .hash "${ED}")
419 if [[ -n ${f} ]] ; then
420 echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log
421 if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then
422 for x in "${QA_FLAGS_IGNORED[@]}" ; do
423 sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log
424 done
425 fi
426 # Filter anything under /usr/lib/debug/ in order to avoid
427 # duplicate warnings for splitdebug files.
428 sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
429 -i "${T}"/scanelf-ignored-LDFLAGS.log
430 f=$(<"${T}"/scanelf-ignored-LDFLAGS.log)
431 if [[ -n ${f} ]] ; then
432 __vecho -ne '\n'
433 eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}"
434 eqawarn " Please include the following list of files in your report:"
435 eqawarn "${f}"
436 __vecho -ne '\n'
437 sleep 1
438 else
439 rm -f "${T}"/scanelf-ignored-LDFLAGS.log
440 fi
441 fi
442 fi
443
444 if [[ ${insecure_rpath} -eq 1 ]] ; then
445 die "Aborting due to serious QA concerns with RUNPATH/RPATH"
446 elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
447 die "Aborting due to QA concerns: ${die_msg}"
448 fi
449
450 # Check for shared libraries lacking SONAMEs
451 qa_var="QA_SONAME_${ARCH/-/_}"
452 eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")"
453 f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
454 if [[ -n ${f} ]] ; then
455 echo "${f}" > "${T}"/scanelf-missing-SONAME.log
456 if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then
457 if [[ ${#QA_SONAME[@]} -gt 1 ]] ; then
458 for x in "${QA_SONAME[@]}" ; do
459 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
460 done
461 else
462 local shopts=$-
463 set -o noglob
464 for x in ${QA_SONAME} ; do
465 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
466 done
467 set +o noglob
468 set -${shopts}
469 fi
470 fi
471 sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log
472 f=$(<"${T}"/scanelf-missing-SONAME.log)
473 if [[ -n ${f} ]] ; then
474 __vecho -ne '\n'
475 eqawarn "QA Notice: The following shared libraries lack a SONAME"
476 eqawarn "${f}"
477 __vecho -ne '\n'
478 sleep 1
479 else
480 rm -f "${T}"/scanelf-missing-SONAME.log
481 fi
482 fi
483
484 # Check for shared libraries lacking NEEDED entries
485 qa_var="QA_DT_NEEDED_${ARCH/-/_}"
486 eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")"
487 f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
488 if [[ -n ${f} ]] ; then
489 echo "${f}" > "${T}"/scanelf-missing-NEEDED.log
490 if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then
491 if [[ ${#QA_DT_NEEDED[@]} -gt 1 ]] ; then
492 for x in "${QA_DT_NEEDED[@]}" ; do
493 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
494 done
495 else
496 local shopts=$-
497 set -o noglob
498 for x in ${QA_DT_NEEDED} ; do
499 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
500 done
501 set +o noglob
502 set -${shopts}
503 fi
504 fi
505 sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log
506 f=$(<"${T}"/scanelf-missing-NEEDED.log)
507 if [[ -n ${f} ]] ; then
508 __vecho -ne '\n'
509 eqawarn "QA Notice: The following shared libraries lack NEEDED entries"
510 eqawarn "${f}"
511 __vecho -ne '\n'
512 sleep 1
513 else
514 rm -f "${T}"/scanelf-missing-NEEDED.log
515 fi
516 fi
517
518 PORTAGE_QUIET=${tmp_quiet}
519 fi
520
521 # Create NEEDED.ELF.2 regardless of RESTRICT=binchecks, since this info is
522 # too useful not to have (it's required for things like preserve-libs), and
523 # it's tempting for ebuild authors to set RESTRICT=binchecks for packages
524 # containing pre-built binaries.
525 if type -P scanelf > /dev/null ; then
526 # Save NEEDED information after removing self-contained providers
527 rm -f "$PORTAGE_BUILDDIR"/build-info/NEEDED{,.ELF.2}
528 scanelf -qyRF '%a;%p;%S;%r;%n' "${D}" | { while IFS= read -r l; do
529 arch=${l%%;*}; l=${l#*;}
530 obj="/${l%%;*}"; l=${l#*;}
531 soname=${l%%;*}; l=${l#*;}
532 rpath=${l%%;*}; l=${l#*;}; [ "${rpath}" = " - " ] && rpath=""
533 needed=${l%%;*}; l=${l#*;}
534 echo "${obj} ${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED
535 echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
536 done }
537
538 [ -n "${QA_SONAME_NO_SYMLINK}" ] && \
539 echo "${QA_SONAME_NO_SYMLINK}" > \
540 "${PORTAGE_BUILDDIR}"/build-info/QA_SONAME_NO_SYMLINK
541
542 if has binchecks ${RESTRICT} && \
543 [ -s "${PORTAGE_BUILDDIR}/build-info/NEEDED.ELF.2" ] ; then
544 eqawarn "QA Notice: RESTRICT=binchecks prevented checks on these ELF files:"
545 eqawarn "$(while read -r x; do x=${x#*;} ; x=${x%%;*} ; echo "${x#${EPREFIX}}" ; done < "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2)"
546 fi
547 fi
548
549 local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')' | sed -e "s:^${ED}:/:")
550 if [[ -n ${unsafe_files} ]] ; then
551 eqawarn "QA Notice: Unsafe files detected (set*id and world writable)"
552 eqawarn "${unsafe_files}"
553 die "Unsafe files found in \${D}. Portage will not install them."
554 fi
555
556 if [[ -d ${D%/}${D} ]] ; then
557 local -i INSTALLTOD=0
558 while read -r -d $'\0' i ; do
559 eqawarn "QA Notice: /${i##${D%/}${D}} installed in \${D}/\${D}"
560 ((INSTALLTOD++))
561 done < <(find "${D%/}${D}" -print0)
562 die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D%/}${D}"
563 fi
564
565 # Sanity check syntax errors in init.d scripts
566 local d
567 for d in /etc/conf.d /etc/init.d ; do
568 [[ -d ${ED}/${d} ]] || continue
569 for i in "${ED}"/${d}/* ; do
570 [[ -L ${i} ]] && continue
571 # if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist
572 [[ ! -e ${i} ]] && continue
573 if [[ ${d} == /etc/init.d && ${i} != *.sh ]] ; then
574 # skip non-shell-script for bug #451386
575 [[ $(head -n1 "${i}") =~ ^#!.*[[:space:]/](runscript|sh)$ ]] || continue
576 fi
577 bash -n "${i}" || die "The init.d file has syntax errors: ${i}"
578 done
579 done
580
581 local checkbashisms=$(type -P checkbashisms)
582 if [[ -n ${checkbashisms} ]] ; then
583 for d in /etc/init.d ; do
584 [[ -d ${ED}${d} ]] || continue
585 for i in "${ED}${d}"/* ; do
586 [[ -e ${i} ]] || continue
587 [[ -L ${i} ]] && continue
588 f=$("${checkbashisms}" -f "${i}" 2>&1)
589 [[ $? != 0 && -n ${f} ]] || continue
590 eqawarn "QA Notice: shell script appears to use non-POSIX feature(s):"
591 while read -r ;
592 do eqawarn " ${REPLY}"
593 done <<< "${f//${ED}}"
594 done
595 done
596 fi
597
598 # Look for leaking LDFLAGS into pkg-config files
599 f=$(egrep -sH '^Libs.*-Wl,(-O[012]|--hash-style)' "${ED}"/usr/*/pkgconfig/*.pc)
600 if [[ -n ${f} ]] ; then
601 eqawarn "QA Notice: pkg-config files with wrong LDFLAGS detected:"
602 eqawarn "${f//${D}}"
603 fi
604
605 # this should help to ensure that all (most?) shared libraries are executable
606 # and that all libtool scripts / static libraries are not executable
607 local j
608 for i in "${ED}"opt/*/lib* \
609 "${ED}"lib* \
610 "${ED}"usr/lib* ; do
611 [[ ! -d ${i} ]] && continue
612
613 for j in "${i}"/*.so.* "${i}"/*.so ; do
614 [[ ! -e ${j} ]] && continue
615 [[ -L ${j} ]] && continue
616 [[ -x ${j} ]] && continue
617 __vecho "making executable: ${j#${ED}}"
618 chmod +x "${j}"
619 done
620
621 for j in "${i}"/*.a "${i}"/*.la ; do
622 [[ ! -e ${j} ]] && continue
623 [[ -L ${j} ]] && continue
624 [[ ! -x ${j} ]] && continue
625 __vecho "removing executable bit: ${j#${ED}}"
626 chmod -x "${j}"
627 done
628
629 for j in "${i}"/*.{a,dll,dylib,sl,so}.* "${i}"/*.{a,dll,dylib,sl,so} ; do
630 [[ ! -e ${j} ]] && continue
631 [[ ! -L ${j} ]] && continue
632 linkdest=$(readlink "${j}")
633 if [[ ${linkdest} == /* ]] ; then
634 __vecho -ne '\n'
635 eqawarn "QA Notice: Found an absolute symlink in a library directory:"
636 eqawarn " ${j#${D}} -> ${linkdest}"
637 eqawarn " It should be a relative symlink if in the same directory"
638 eqawarn " or a linker script if it crosses the /usr boundary."
639 fi
640 done
641 done
642
643 # When installing static libraries into /usr/lib and shared libraries into
644 # /lib, we have to make sure we have a linker script in /usr/lib along side
645 # the static library, or gcc will utilize the static lib when linking :(.
646 # http://bugs.gentoo.org/4411
647 abort="no"
648 local a s
649 for a in "${ED}"usr/lib*/*.a ; do
650 s=${a%.a}.so
651 if [[ ! -e ${s} ]] ; then
652 s=${s%usr/*}${s##*/usr/}
653 if [[ -e ${s} ]] ; then
654 __vecho -ne '\n'
655 eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}"
656 abort="yes"
657 fi
658 fi
659 done
660 [[ ${abort} == "yes" ]] && die "add those ldscripts"
661
662 # Make sure people don't store libtool files or static libs in /lib
663 f=$(ls "${ED}"lib*/*.{a,la} 2>/dev/null)
664 if [[ -n ${f} ]] ; then
665 __vecho -ne '\n'
666 eqawarn "QA Notice: Excessive files found in the / partition"
667 eqawarn "${f}"
668 __vecho -ne '\n'
669 die "static archives (*.a) and libtool library files (*.la) belong in /usr/lib*, not /lib*"
670 fi
671
672 # Verify that the libtool files don't contain bogus $D entries.
673 local abort=no gentoo_bug=no always_overflow=no
674 for a in "${ED}"usr/lib*/*.la ; do
675 s=${a##*/}
676 if grep -qs "${ED}" "${a}" ; then
677 __vecho -ne '\n'
678 eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths"
679 abort="yes"
680 fi
681 done
682 [[ ${abort} == "yes" ]] && die "soiled libtool library files found"
683
684 # Evaluate misc gcc warnings
685 if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then
686 # In debug mode, this variable definition and corresponding grep calls
687 # will produce false positives if they're shown in the trace.
688 local reset_debug=0
689 if [[ ${-/x/} != $- ]] ; then
690 set +x
691 reset_debug=1
692 fi
693 local m msgs=(
694 ": warning: dereferencing type-punned pointer will break strict-aliasing rules"
695 ": warning: dereferencing pointer .* does break strict-aliasing rules"
696 ": warning: implicit declaration of function"
697 ": warning: incompatible implicit declaration of built-in function"
698 ": warning: is used uninitialized in this function" # we'll ignore "may" and "might"
699 ": warning: comparisons like X<=Y<=Z do not have their mathematical meaning"
700 ": warning: null argument where non-null required"
701 ": warning: array subscript is below array bounds"
702 ": warning: array subscript is above array bounds"
703 ": warning: attempt to free a non-heap object"
704 ": warning: .* called with .*bigger.* than .* destination buffer"
705 ": warning: call to .* will always overflow destination buffer"
706 ": warning: assuming pointer wraparound does not occur when comparing"
707 ": warning: hex escape sequence out of range"
708 ": warning: [^ ]*-hand operand of comma .*has no effect"
709 ": warning: converting to non-pointer type .* from NULL"
710 ": warning: NULL used in arithmetic"
711 ": warning: passing NULL to non-pointer argument"
712 ": warning: the address of [^ ]* will always evaluate as"
713 ": warning: the address of [^ ]* will never be NULL"
714 ": warning: too few arguments for format"
715 ": warning: reference to local variable .* returned"
716 ": warning: returning reference to temporary"
717 ": warning: function returns address of local variable"
718 ": warning: .*\\[-Wsizeof-pointer-memaccess\\]"
719 ": warning: .*\\[-Waggressive-loop-optimizations\\]"
720 # this may be valid code :/
721 #": warning: multi-character character constant"
722 # need to check these two ...
723 #": warning: assuming signed overflow does not occur when"
724 #": warning: comparison with string literal results in unspecified behav"
725 # yacc/lex likes to trigger this one
726 #": warning: extra tokens at end of .* directive"
727 # only gcc itself triggers this ?
728 #": warning: .*noreturn.* function does return"
729 # these throw false positives when 0 is used instead of NULL
730 #": warning: missing sentinel in function call"
731 #": warning: not enough variable arguments to fit a sentinel"
732 )
733 abort="no"
734 i=0
735 local grep_cmd=grep
736 [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep
737 while [[ -n ${msgs[${i}]} ]] ; do
738 m=${msgs[$((i++))]}
739 # force C locale to work around slow unicode locales #160234
740 f=$(LC_ALL=C $grep_cmd "${m}" "${PORTAGE_LOG_FILE}")
741 if [[ -n ${f} ]] ; then
742 abort="yes"
743 # for now, don't make this fatal (see bug #337031)
744 #case "$m" in
745 # ": warning: call to .* will always overflow destination buffer") always_overflow=yes ;;
746 #esac
747 if [[ $always_overflow = yes ]] ; then
748 eerror
749 eerror "QA Notice: Package triggers severe warnings which indicate that it"
750 eerror " may exhibit random runtime failures."
751 eerror
752 eerror "${f}"
753 eerror
754 eerror " Please file a bug about this at http://bugs.gentoo.org/"
755 eerror " with the maintaining herd of the package."
756 eerror
757 else
758 __vecho -ne '\n'
759 eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
760 eqawarn " may exhibit random runtime failures."
761 eqawarn "${f}"
762 __vecho -ne '\n'
763 fi
764 fi
765 done
766 local cat_cmd=cat
767 [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat
768 [[ $reset_debug = 1 ]] && set -x
769 # Use safe cwd, avoiding unsafe import for bug #469338.
770 f=$(cd "${PORTAGE_PYM_PATH}" ; $cat_cmd "${PORTAGE_LOG_FILE}" | \
771 "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed")
772 if [[ -n ${f} ]] ; then
773
774 # In the future this will be a forced "die". In preparation,
775 # increase the log level from "qa" to "eerror" so that people
776 # are aware this is a problem that must be fixed asap.
777
778 # just warn on 32bit hosts but bail on 64bit hosts
779 case ${CHOST} in
780 alpha*|hppa64*|ia64*|powerpc64*|mips64*|sparc64*|sparcv9*|x86_64*) gentoo_bug=yes ;;
781 esac
782
783 abort=yes
784
785 if [[ $gentoo_bug = yes ]] ; then
786 eerror
787 eerror "QA Notice: Package triggers severe warnings which indicate that it"
788 eerror " will almost certainly crash on 64bit architectures."
789 eerror
790 eerror "${f}"
791 eerror
792 eerror " Please file a bug about this at http://bugs.gentoo.org/"
793 eerror " with the maintaining herd of the package."
794 eerror
795 else
796 __vecho -ne '\n'
797 eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
798 eqawarn " will almost certainly crash on 64bit architectures."
799 eqawarn "${f}"
800 __vecho -ne '\n'
801 fi
802
803 fi
804 if [[ ${abort} == "yes" ]] ; then
805 if [[ $gentoo_bug = yes || $always_overflow = yes ]] ; then
806 die "install aborted due to severe warnings shown above"
807 else
808 echo "Please do not file a Gentoo bug and instead" \
809 "report the above QA issues directly to the upstream" \
810 "developers of this software." | fmt -w 70 | \
811 while read -r line ; do eqawarn "${line}" ; done
812 eqawarn "Homepage: ${HOMEPAGE}"
813 has stricter ${FEATURES} && \
814 die "install aborted due to severe warnings shown above"
815 fi
816 fi
817 fi
818
819 # Portage regenerates this on the installed system.
820 rm -f "${ED}"/usr/share/info/dir{,.gz,.bz2} || die "rm failed!"
821
822 if has multilib-strict ${FEATURES} && \
823 [[ -x /usr/bin/file && -x /usr/bin/find ]] && \
824 [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]]
825 then
826 rm -f "${T}/multilib-strict.log"
827 local abort=no dir file
828 MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g')
829 for dir in ${MULTILIB_STRICT_DIRS} ; do
830 [[ -d ${ED}/${dir} ]] || continue
831 for file in $(find ${ED}/${dir} -type f | grep -v "^${ED}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do
832 if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then
833 echo "${file#${ED}//}" >> "${T}/multilib-strict.log"
834 fi
835 done
836 done
837
838 if [[ -s ${T}/multilib-strict.log ]] ; then
839 if [[ ${#QA_MULTILIB_PATHS[@]} -eq 1 ]] ; then
840 local shopts=$-
841 set -o noglob
842 QA_MULTILIB_PATHS=(${QA_MULTILIB_PATHS})
843 set +o noglob
844 set -${shopts}
845 fi
846 if [ "${QA_STRICT_MULTILIB_PATHS-unset}" = unset ] ; then
847 for x in "${QA_MULTILIB_PATHS[@]}" ; do
848 sed -e "s#^${x#/}\$##" -i "${T}/multilib-strict.log"
849 done
850 sed -e "/^\$/d" -i "${T}/multilib-strict.log"
851 fi
852 if [[ -s ${T}/multilib-strict.log ]] ; then
853 abort=yes
854 echo "Files matching a file type that is not allowed:"
855 while read -r ; do
856 echo " ${REPLY}"
857 done < "${T}/multilib-strict.log"
858 fi
859 fi
860
861 [[ ${abort} == yes ]] && die "multilib-strict check failed!"
862 fi
863 }
864
865 install_qa_check_prefix() {
866 if [[ -d ${ED}/${D} ]] ; then
867 find "${ED}/${D}" | \
868 while read i ; do
869 eqawarn "QA Notice: /${i##${ED}/${D}} installed in \${ED}/\${D}"
870 done
871 die "Aborting due to QA concerns: files installed in ${ED}/${D}"
872 fi
873
874 if [[ -d ${ED}/${EPREFIX} ]] ; then
875 find "${ED}/${EPREFIX}/" | \
876 while read i ; do
877 eqawarn "QA Notice: ${i#${D}} double prefix"
878 done
879 die "Aborting due to QA concerns: double prefix files installed"
880 fi
881
882 if [[ -d ${D} ]] ; then
883 INSTALLTOD=$(find ${D%/} | egrep -v "^${ED}" | sed -e "s|^${D%/}||" | awk '{if (length($0) <= length("'"${EPREFIX}"'")) { if (substr("'"${EPREFIX}"'", 1, length($0)) != $0) {print $0;} } else if (substr($0, 1, length("'"${EPREFIX}"'")) != "'"${EPREFIX}"'") {print $0;} }')
884 if [[ -n ${INSTALLTOD} ]] ; then
885 eqawarn "QA Notice: the following files are outside of the prefix:"
886 eqawarn "${INSTALLTOD}"
887 die "Aborting due to QA concerns: there are files installed outside the prefix"
888 fi
889 fi
890
891 # all further checks rely on ${ED} existing
892 [[ -d ${ED} ]] || return
893
894 # check shebangs, bug #282539
895 rm -f "${T}"/non-prefix-shebangs-errs
896 local WHITELIST=" /usr/bin/env "
897 # this is hell expensive, but how else?
898 find "${ED}" -executable \! -type d -print0 \
899 | xargs -0 grep -H -n -m1 "^#!" \
900 | while read f ;
901 do
902 local fn=${f%%:*}
903 local pos=${f#*:} ; pos=${pos%:*}
904 local line=${f##*:}
905 # shebang always appears on the first line ;)
906 [[ ${pos} != 1 ]] && continue
907 local oldIFS=${IFS}
908 IFS=$'\r'$'\n'$'\t'" "
909 line=( ${line#"#!"} )
910 IFS=${oldIFS}
911 [[ ${WHITELIST} == *" ${line[0]} "* ]] && continue
912 local fp=${fn#${D}} ; fp=/${fp%/*}
913 # line[0] can be an absolutised path, bug #342929
914 local eprefix=$(canonicalize ${EPREFIX})
915 local rf=${fn}
916 # in case we deal with a symlink, make sure we don't replace it
917 # with a real file (sed -i does that)
918 if [[ -L ${fn} ]] ; then
919 rf=$(readlink ${fn})
920 [[ ${rf} != /* ]] && rf=${fn%/*}/${rf}
921 # ignore symlinks pointing to outside prefix
922 # as seen in sys-devel/native-cctools
923 [[ $(canonicalize "/${rf#${D}}") != ${eprefix}/* ]] && continue
924 fi
925 # does the shebang start with ${EPREFIX}, and does it exist?
926 if [[ ${line[0]} == ${EPREFIX}/* || ${line[0]} == ${eprefix}/* ]] ; then
927 if [[ ! -e ${ROOT%/}${line[0]} && ! -e ${D%/}${line[0]} ]] ; then
928 # hmm, refers explicitly to $EPREFIX, but doesn't exist,
929 # if it's in PATH that's wrong in any case
930 if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
931 echo "${fn#${D}}:${line[0]} (explicit EPREFIX but target not found)" \
932 >> "${T}"/non-prefix-shebangs-errs
933 else
934 eqawarn "${fn#${D}} has explicit EPREFIX in shebang but target not found (${line[0]})"
935 fi
936 fi
937 continue
938 fi
939 # unprefixed shebang, is the script directly in $PATH?
940 if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
941 if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; then
942 # is it unprefixed, but we can just fix it because a
943 # prefixed variant exists
944 eqawarn "prefixing shebang of ${fn#${D}}"
945 # statement is made idempotent on purpose, because
946 # symlinks may point to the same target, and hence the
947 # same real file may be sedded multiple times since we
948 # read the shebangs in one go upfront for performance
949 # reasons
950 sed -i -e '1s:^#! \?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}"
951 continue
952 else
953 # this is definitely wrong: script in $PATH and invalid shebang
954 echo "${fn#${D}}:${line[0]} (script ${fn##*/} installed in PATH but interpreter ${line[0]} not found)" \
955 >> "${T}"/non-prefix-shebangs-errs
956 fi
957 else
958 # unprefixed/invalid shebang, but outside $PATH, this may be
959 # intended (e.g. config.guess) so remain silent by default
960 has stricter ${FEATURES} && \
961 eqawarn "invalid shebang in ${fn#${D}}: ${line[0]}"
962 fi
963 done
964 if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then
965 eqawarn "QA Notice: the following files use invalid (possible non-prefixed) shebangs:"
966 while read line ; do
967 eqawarn " ${line}"
968 done < "${T}"/non-prefix-shebangs-errs
969 rm -f "${T}"/non-prefix-shebangs-errs
970 die "Aborting due to QA concerns: invalid shebangs found"
971 fi
972 }
973
974 install_mask() {
975 local root="$1"
976 shift
977 local install_mask="$*"
978
979 # we don't want globbing for initial expansion, but afterwards, we do
980 local shopts=$-
981 set -o noglob
982 local no_inst
983 for no_inst in ${install_mask}; do
984 set +o noglob
985 __quiet_mode || einfo "Removing ${no_inst}"
986 # normal stuff
987 rm -Rf "${root}"/${no_inst} >&/dev/null
988
989 # we also need to handle globs (*.a, *.h, etc)
990 find "${root}" \( -path "${no_inst}" -or -name "${no_inst}" \) \
991 -exec rm -fR {} \; >/dev/null 2>&1
992 done
993 # set everything back the way we found it
994 set +o noglob
995 set -${shopts}
996 }
997
998 preinst_mask() {
999 if [ -z "${D}" ]; then
1000 eerror "${FUNCNAME}: D is unset"
1001 return 1
1002 fi
1003
1004 if ! ___eapi_has_prefix_variables; then
1005 local ED=${D}
1006 fi
1007
1008 # Make sure $PWD is not ${D} so that we don't leave gmon.out files
1009 # in there in case any tools were built with -pg in CFLAGS.
1010 cd "${T}"
1011
1012 # remove man pages, info pages, docs if requested
1013 local f
1014 for f in man info doc; do
1015 if has no${f} $FEATURES; then
1016 INSTALL_MASK="${INSTALL_MASK} /usr/share/${f}"
1017 fi
1018 done
1019
1020 install_mask "${ED}" "${INSTALL_MASK}"
1021
1022 # remove share dir if unnessesary
1023 if has nodoc $FEATURES || has noman $FEATURES || has noinfo $FEATURES; then
1024 rmdir "${ED}usr/share" &> /dev/null
1025 fi
1026 }
1027
1028 preinst_sfperms() {
1029 if [ -z "${D}" ]; then
1030 eerror "${FUNCNAME}: D is unset"
1031 return 1
1032 fi
1033
1034 if ! ___eapi_has_prefix_variables; then
1035 local ED=${D}
1036 fi
1037
1038 # Smart FileSystem Permissions
1039 if has sfperms $FEATURES; then
1040 local i
1041 find "${ED}" -type f -perm -4000 -print0 | \
1042 while read -r -d $'\0' i ; do
1043 if [ -n "$(find "$i" -perm -2000)" ] ; then
1044 ebegin ">>> SetUID and SetGID: [chmod o-r] /${i#${ED}}"
1045 chmod o-r "$i"
1046 eend $?
1047 else
1048 ebegin ">>> SetUID: [chmod go-r] /${i#${ED}}"
1049 chmod go-r "$i"
1050 eend $?
1051 fi
1052 done
1053 find "${ED}" -type f -perm -2000 -print0 | \
1054 while read -r -d $'\0' i ; do
1055 if [ -n "$(find "$i" -perm -4000)" ] ; then
1056 # This case is already handled
1057 # by the SetUID check above.
1058 true
1059 else
1060 ebegin ">>> SetGID: [chmod o-r] /${i#${ED}}"
1061 chmod o-r "$i"
1062 eend $?
1063 fi
1064 done
1065 fi
1066 }
1067
1068 preinst_suid_scan() {
1069 if [ -z "${D}" ]; then
1070 eerror "${FUNCNAME}: D is unset"
1071 return 1
1072 fi
1073
1074 if ! ___eapi_has_prefix_variables; then
1075 local ED=${D}
1076 fi
1077
1078 # total suid control.
1079 if has suidctl $FEATURES; then
1080 local i sfconf x
1081 sfconf=${PORTAGE_CONFIGROOT}etc/portage/suidctl.conf
1082 # sandbox prevents us from writing directly
1083 # to files outside of the sandbox, but this
1084 # can easly be bypassed using the addwrite() function
1085 addwrite "${sfconf}"
1086 __vecho ">>> Performing suid scan in ${ED}"
1087 for i in $(find "${ED}" -type f \( -perm -4000 -o -perm -2000 \) ); do
1088 if [ -s "${sfconf}" ]; then
1089 install_path=/${i#${ED}}
1090 if grep -q "^${install_path}\$" "${sfconf}" ; then
1091 __vecho "- ${install_path} is an approved suid file"
1092 else
1093 __vecho ">>> Removing sbit on non registered ${install_path}"
1094 for x in 5 4 3 2 1 0; do sleep 0.25 ; done
1095 ls_ret=$(ls -ldh "${i}")
1096 chmod ugo-s "${i}"
1097 grep "^#${install_path}$" "${sfconf}" > /dev/null || {
1098 __vecho ">>> Appending commented out entry to ${sfconf} for ${PF}"
1099 echo "## ${ls_ret%${ED}*}${install_path}" >> "${sfconf}"
1100 echo "#${install_path}" >> "${sfconf}"
1101 # no delwrite() eh?
1102 # delwrite ${sconf}
1103 }
1104 fi
1105 else
1106 __vecho "suidctl feature set but you are lacking a ${sfconf}"
1107 fi
1108 done
1109 fi
1110 }
1111
1112 preinst_selinux_labels() {
1113 if [ -z "${D}" ]; then
1114 eerror "${FUNCNAME}: D is unset"
1115 return 1
1116 fi
1117 if has selinux ${FEATURES}; then
1118 # SELinux file labeling (needs to execute after preinst)
1119 # only attempt to label if setfiles is executable
1120 # and 'context' is available on selinuxfs.
1121 if [ -f /selinux/context -o -f /sys/fs/selinux/context ] && \
1122 [ -x /usr/sbin/setfiles -a -x /usr/sbin/selinuxconfig ]; then
1123 __vecho ">>> Setting SELinux security labels"
1124 (
1125 eval "$(/usr/sbin/selinuxconfig)" || \
1126 die "Failed to determine SELinux policy paths.";
1127
1128 addwrite /selinux/context
1129 addwrite /sys/fs/selinux/context
1130
1131 /usr/sbin/setfiles "${file_contexts_path}" -r "${D}" "${D}"
1132 ) || die "Failed to set SELinux security labels."
1133 else
1134 # nonfatal, since merging can happen outside a SE kernel
1135 # like during a recovery situation
1136 __vecho "!!! Unable to set SELinux security labels"
1137 fi
1138 fi
1139 }
1140
1141 __dyn_package() {
1142 local PROOT
1143
1144 if ! ___eapi_has_prefix_variables; then
1145 local EPREFIX= ED=${D}
1146 fi
1147
1148 # Make sure $PWD is not ${D} so that we don't leave gmon.out files
1149 # in there in case any tools were built with -pg in CFLAGS.
1150
1151 cd "${T}"
1152
1153 if [[ -n ${PKG_INSTALL_MASK} ]] ; then
1154 PROOT=${T}/packaging/
1155 # make a temporary copy of ${D} so that any modifications we do that
1156 # are binpkg specific, do not influence the actual installed image.
1157 rm -rf "${PROOT}" || die "failed removing stale package tree"
1158 cp -pPR $(cp --help | grep -qs -e-l && echo -l) \
1159 "${D}" "${PROOT}" \
1160 || die "failed creating packaging tree"
1161
1162 install_mask "${PROOT%/}${EPREFIX}/" "${PKG_INSTALL_MASK}"
1163 else
1164 PROOT=${D}
1165 fi
1166
1167 local tar_options=""
1168 [[ $PORTAGE_VERBOSE = 1 ]] && tar_options+=" -v"
1169 has xattr ${FEATURES} && [[ $(tar --help 2> /dev/null) == *--xattrs* ]] && tar_options+=" --xattrs"
1170 # Sandbox is disabled in case the user wants to use a symlink
1171 # for $PKGDIR and/or $PKGDIR/All.
1172 export SANDBOX_ON="0"
1173 [ -z "${PORTAGE_BINPKG_TMPFILE}" ] && \
1174 die "PORTAGE_BINPKG_TMPFILE is unset"
1175 mkdir -p "${PORTAGE_BINPKG_TMPFILE%/*}" || die "mkdir failed"
1176 tar $tar_options -cf - $PORTAGE_BINPKG_TAR_OPTS -C "${PROOT}" . | \
1177 $PORTAGE_BZIP2_COMMAND -c > "$PORTAGE_BINPKG_TMPFILE"
1178 assert "failed to pack binary package: '$PORTAGE_BINPKG_TMPFILE'"
1179 PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
1180 "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/xpak-helper.py recompose \
1181 "$PORTAGE_BINPKG_TMPFILE" "$PORTAGE_BUILDDIR/build-info"
1182 if [ $? -ne 0 ]; then
1183 rm -f "${PORTAGE_BINPKG_TMPFILE}"
1184 die "Failed to append metadata to the tbz2 file"
1185 fi
1186 local md5_hash=""
1187 if type md5sum &>/dev/null ; then
1188 md5_hash=$(md5sum "${PORTAGE_BINPKG_TMPFILE}")
1189 md5_hash=${md5_hash%% *}
1190 elif type md5 &>/dev/null ; then
1191 md5_hash=$(md5 "${PORTAGE_BINPKG_TMPFILE}")
1192 md5_hash=${md5_hash##* }
1193 fi
1194 [ -n "${md5_hash}" ] && \
1195 echo ${md5_hash} > "${PORTAGE_BUILDDIR}"/build-info/BINPKGMD5
1196 __vecho ">>> Done."
1197
1198 # cleanup our temp tree
1199 [[ -n ${PKG_INSTALL_MASK} ]] && rm -rf "${PROOT}"
1200 cd "${PORTAGE_BUILDDIR}"
1201 >> "$PORTAGE_BUILDDIR/.packaged" || \
1202 die "Failed to create $PORTAGE_BUILDDIR/.packaged"
1203 }
1204
1205 __dyn_spec() {
1206 local sources_dir=${T}/rpmbuild/SOURCES
1207 mkdir -p "${sources_dir}"
1208 declare -a tar_args=("${EBUILD}")
1209 [[ -d ${FILESDIR} ]] && tar_args=("${EBUILD}" "${FILESDIR}")
1210 tar czf "${sources_dir}/${PF}.tar.gz" \
1211 "${tar_args[@]}" || \
1212 die "Failed to create base rpm tarball."
1213
1214 cat <<__END1__ > ${PF}.spec
1215 Summary: ${DESCRIPTION}
1216 Name: ${PN}
1217 Version: ${PV}
1218 Release: ${PR}
1219 License: GPL
1220 Group: portage/${CATEGORY}
1221 Source: ${PF}.tar.gz
1222 %description
1223 ${DESCRIPTION}
1224
1225 ${HOMEPAGE}
1226
1227 %prep
1228 %setup -c
1229
1230 %build
1231
1232 %install
1233
1234 %clean
1235
1236 %files
1237 /
1238 __END1__
1239
1240 }
1241
1242 __dyn_rpm() {
1243 if ! ___eapi_has_prefix_variables; then
1244 local EPREFIX=
1245 fi
1246
1247 cd "${T}" || die "cd failed"
1248 local machine_name=${CHOST%%-*}
1249 local dest_dir=${T}/rpmbuild/RPMS/${machine_name}
1250 addwrite "${RPMDIR}"
1251 __dyn_spec
1252 HOME=${T} \
1253 rpmbuild -bb --clean --nodeps --rmsource "${PF}.spec" --buildroot "${D}" --target "${CHOST}" || die "Failed to integrate rpm spec file"
1254 install -D "${dest_dir}/${PN}-${PV}-${PR}.${machine_name}.rpm" \
1255 "${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || \
1256 die "Failed to move rpm"
1257 }
1258
1259 die_hooks() {
1260 [[ -f $PORTAGE_BUILDDIR/.die_hooks ]] && return
1261 local x
1262 for x in $EBUILD_DEATH_HOOKS ; do
1263 $x >&2
1264 done
1265 > "$PORTAGE_BUILDDIR/.die_hooks"
1266 }
1267
1268 success_hooks() {
1269 local x
1270 for x in $EBUILD_SUCCESS_HOOKS ; do
1271 $x
1272 done
1273 }
1274
1275 install_hooks() {
1276 local hooks_dir="${PORTAGE_CONFIGROOT}etc/portage/hooks/install"
1277 local fp
1278 local ret=0
1279 shopt -s nullglob
1280 for fp in "${hooks_dir}"/*; do
1281 if [ -x "$fp" ]; then
1282 "$fp"
1283 ret=$(( $ret | $? ))
1284 fi
1285 done
1286 shopt -u nullglob
1287 return $ret
1288 }
1289
1290 if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then
1291 __source_all_bashrcs
1292 [ "$PORTAGE_DEBUG" == "1" ] && set -x
1293 for x in ${MISC_FUNCTIONS_ARGS}; do
1294 ${x}
1295 done
1296 unset x
1297 [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE"
1298 if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
1299 [[ ! -s $SANDBOX_LOG ]]
1300 "$PORTAGE_BIN_PATH"/ebuild-ipc exit $?
1301 fi
1302 fi
1303
1304 :