#!/bin/bash -e # Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 ROOT="/" LDSO_CONF="/etc/ld.so.conf" if [[ ! -e $LDSO_CONF ]]; then echo "$LDSO_CONF not found" >&2 exit 1 fi LDSO_CONF_DIR=$(dirname $LDSO_CONF) VERBOSE=0 UPDATE_LINKS=1 get_options() { while getopts "vnNXf:C:r:p" opt "$@"; do case $opt in v) echo "ldconfig for musl in Gentoo" VERBOSE=1 ;; r) ROOT=$OPTARG ;; f) LDSO_CONF=$OPTARG ;; X) UPDATE_LINKS=0 ;; \?) echo "Invalid option: -$opt" >&2 exit 1 ;; n|N|C|p) echo "Unimplemented option: -$opt" >&2 exit 1 ;; esac done if [[ $UPDATE_LINKS == 1 ]]; then echo "Updating links is not implemented." fi } repeated() { local l=$1 local drs="${@:2}" for m in $drs; do [[ $m == $l ]] && return 0 done return 1 } expand() { # We are assuming the ld.so.conf's 'include' is not recursive local f line l local glob="$LDSO_CONF_DIR/$1" local drs="${@:2} " for f in $glob; do [[ ! -f $f ]] && continue while read line; do line=${line%%#*} line=${line//:/ } line=${line//,/ } for l in $line; do #We must add this whether or not the directory exists repeated $l $drs && continue drs+=" $l " done done < $f done echo $drs } multilib_filter() { local l="$1" local arch="$2" local drs="${@:3}" if [[ "${arch}" == "x32" ]] ; then if [[ "$l" =~ "/32" || "$l" =~ "lib32" || "$l" =~ "/64" || "$l" =~ "lib64" ]] ; then #trash return 1 else return 0 fi elif [[ "${arch}" == "i386" ]] ; then if [[ "$l" == "/lib" || "$l" == "/usr/lib" || "$l" == "/usr/local/lib" ]] ; then return 1 fi if [[ "$l" =~ "/32" || "$l" =~ "lib32" ]] ; then #keep return 0 else return 1 fi elif [[ "${arch}" == "x86_64" ]] ; then if [[ "$l" == "/lib" || "$l" == "/usr/lib" || "$l" == "/usr/local/lib" ]] ; then return 1 fi if [[ "$l" =~ "/64" || "$l" =~ "lib64" ]] ; then #keep return 0 else return 1 fi fi return 0 } read_ldso_conf() { local drs=" " local arch="$2" while read line; do # Sanitize the line - see ldconfig(8) for delimiters # Note: bash read turns tabs into spaces and read already # delimits on newlines with the default $IFS line=${line%%#*} # Remove comments line=${line//:/ } # Change colon delimiter to space line=${line//,/ } # Change comma delimiter to space next=0 for l in $line; do if [[ $next == 1 ]]; then next=0 drs=$(expand $l $drs) elif [[ $l == "include" ]]; then next=1 else # glibc's ldconfig silently skips non directories if [[ -d $l ]]; then repeated $l $drs && continue multilib_filter $l $arch $drs || continue drs+=" $l " fi fi done done < $1 echo $drs } sanitize() { local drs=$@ repeated "/lib" $drs || drs="/lib $drs" repeated "/usr/lib" $drs || drs="/usr/lib $drs" echo $drs } get_options "$@" for arch in @@ARCHES@@ ; do echo "Updating $arch" ARCH=$arch drs=$(read_ldso_conf "$LDSO_CONF" "$ARCH") if [[ "${arch}" == "@@ARCH@@" ]] ; then drs=$(sanitize $drs) fi libdir= case $arch in i386) libdir="lib32" ;; x86_64) libdir="lib64" ;; x32) libdir="libx32" ;; esac LDSO_PATH="/${libdir}/ld-musl-${ARCH}.so.1" if [[ ! -e $LDSO_PATH ]]; then echo "$LDSO_PATH not found" >&2 exit 1 fi LDSO_ARCH=$(basename $LDSO_PATH) LDSO_NAME=${LDSO_ARCH%.so.1} ETC_LDSO_PATH=/etc/${LDSO_NAME}.path X=$(mktemp -p /tmp ${LDSO_NAME}.XXXXXX) for d in $drs; do echo $d >> $X done chmod 644 $X mv $X $ETC_LDSO_PATH done