#!/bin/bash # # Common functions to copy binaries and their dependancies. # ############################################################ # # Usage: get_dynamic_dependencies [-l ] # * the list must be seperated by spaces # * the search for lib needed by a binary can be done locally, # using the -l option # # Ouput: # Will simply echo list of required libraries # List of libraries to exclude from BLACKLIST="ld-linux linux-gate linux-vdso libc.so" LOCALSEARCH=0 LOCALSEARCHDIR="" get_dynamic_dependencies() { if [ "x$1" == "x-l" ]; then LOCALSEARCH=1 pdebug "Local search activated." shift [ ! -d $1 ] && perror "Directory given does not exist, exiting." LOCALSEARCHDIR=$1 shift pdebug "Looking in: $LOCALSEARCHDIR" fi while [ $# != 0 ]; do local BINARY=$1 shift pdebug "Processing $BINARY ..." local LDD_OUT="ldd_output" if ldd $BINARY > $LDD_OUT; then # Case 1: dynamic for LIB in $(cat $LDD_OUT | grep -v $(echo $BLACKLIST|sed 's/ /\\|/g') | awk '{print $1 $2 $3}'); do # split the entry into an array, ex: # libm.so.6 => /lib/libm.so.6 would be split into: # liblink[0] liblink[1] local liblink=(${LIB//=>/ }) lib_search done else # Case 2: not a dynamic pdebug "$BINARY not a dynamic, skipping." rm -f $LDD_OUT continue fi rm -f $LDD_OUT done } lib_search(){ pdebug "\tSearching for ${liblink[0]}..." # if activated, start by searching the lib locally if [ "x$LOCALSEARCH" == "x1" ]; then cd $LOCALSEARCHDIR local LOCAL_MATCHES=$(find . -name "${liblink[0]}") # | awk -F '.' '{print $1}')".so\*) cd - &>/dev/null if [ "x${LOCAL_MATCHES}" != "x" ]; then for llib in ${LOCAL_MATCHES}; do pdebug "\t\tFound locally, copying ${LOCALSEARCHDIR}/${llib}" get_link_chain "${LOCALSEARCHDIR}"/"${llib}" "${LOCALSEARCHDIR}" get_dynamic_dependencies -l "${LOCALSEARCHDIR}" "${llib}" done # found the libs, we are done return fi # mark local search as done fi # search the lib on the system since it was not found earlier if [ ! -z ${liblink[1]} ] && [ "x${liblink[1]}" != "xnot" ]; then pdebug "\t\tNot found locally but in system, copying ${liblink[1]}" # get chain of symlink for that lib get_link_chain ${liblink[1]} else pwarning "\t\tLib '${liblink[0]}' from required dir '$ENTRY' neither found in build directory nor on this system." pwarning "\t\tIf this lib is not supplied by another module, this module will probably fail in your final system" fi } ############################################################ # # Usage: get_link_chain [prefix] # # must be in absolute form- # [prefix] is the prefix to strip from the ouput. # # Output: # Lists the symlink chain until a hardlink is found. get_link_chain() { # sanity checks if [[ "$1" == /* ]]; then [ -e $1 ] || perror "get_link_chain: no such file: $1" else perror "get_link_chain() requires absolute paths, given: $1" fi if [ $# == 2 ] ; then [ ! -d $2 ] && perror "get_link_chain: $2 is not a directory." # got a prefix local PREFIX=$2 else # mark prefix as not set local PREFIX="notset" fi # canonalize local LINK=$(canonicalize $1) local CHAIN="$LINK" # write the first link in the chain if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then # prefix was not in the link echo "$LINK" else # prefix was in the link echo ./"${LINK#$PREFIX}" fi else # no prefix, copy like it is echo "$LINK" fi # now we check for symlinks local TRY=0 while [ -L $LINK ] && [ $TRY -lt 10 ]; do let TRY=TRY+1 # save the directory prefix CURRENTDIR=$(dirname ${LINK}) # first follow the link LINK=$(readlink $LINK) CHAIN+=" -> $LINK" # $LINK can be absolute or relative, check cases [[ "$LINK" == /* ]] || LINK=$(canonicalize "$CURRENTDIR"/"${LINK}") # write the first link in the chain if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then # prefix was not in the link echo "$LINK" else # prefix was in the link echo ./"${LINK#$PREFIX}" fi else # no prefix, copy like it is echo "$LINK" fi done pdebug "\t\tCHAIN: $CHAIN" } # Function to get libc and ld-linux list_basic_libs() { for i in $(ldd ${SHELL}) do [ $(echo $i | grep '^/' | grep -c ld) -eq 1 -o $(echo $i | grep '^/' | grep -c libc.so) -eq 1 ] && get_link_chain $i done }