#!/usr/bin/env bash set -eu VDN_PATH=$(readlink -f $(dirname $(whereis vdn| cut -d ' ' -f 2))/..) REVERSE=0 TRACE=0 export SLASH=$VDN_PATH/slash help() { cat << EOF `basename $0` create slash directoty. `synopsis` -h : affiche cette aide -t : lance vdn en mode trace. La capture est placée dans /tmp/vdn.trace (*) -r : replace par un shebang classique. (*) le fichier capture (/tmp/vdn.trace) est utilisé s'il existe par `basename $0`. EOF } synopsis() { cat << EOF Usage : `basename $0` [-h] [-r] `basename $0` -t EOF } usage() { synopsis exit 2 } args() { local opt while getopts "hrt" opt; do case $opt in h) help; exit 0;; r) REVERSE=1;; t) TRACE=1;; ?) usage;; esac done shift $(($OPTIND - 1)) } getTrace() { strace -f -e trace=file $@ 2>&1 | \ egrep -v 'ENOENT|unfinished|resumed|attached|exited|SIG' | \ sed -re 's/^.*"(.*)".*$/\1/' | \ grep -v $VDN_PATH | \ grep -v $HOME | \ egrep '^/' | \ egrep -v '^/proc|^/etc|^/var|^/tmp/|^/run/|^/sys/|^/dev|^.$' | \ egrep -v '^/home|^/tmp' | \ sort -u > /tmp/trace.vdn } copy() { s=$SLASH r='^#' while read f; do [ -z "$f" ] && continue [[ $f =~ $r ]] && continue #[ $f = "/bin/bash" ] && continue [ -d $f ] && continue [ -f $f -o -L $f ] || { echo "copy : BAD : $f" continue } #echo ":$f" d=$(dirname $f) [ ! -d $s/$d ] && mkdir -p $s/$d || : cp -a $f $s/$d || : if [ -L $f ]; then dst=$(readlink $f) if [[ $dst =~ ^/ ]]; then echo "ABS ($f) > $dst" n=$(($(echo $f | sed -re 's/[^/]//g' | wc -c) -2)) p=$(ruby -e "puts \"../\"*$n") b=$(basename $f) rm $s/$d/$b #ln -sf $s/$dst $s/$d/$b ln -sf $p/$dst $s/$d/$b echo $dst | copy elif [[ $dst =~ ^/ ]]; then echo "REL ($f) > $dst" echo $dst | copy else echo $d/$dst | copy fi fi #echo "==> $f" done } findLibIte() { local i e while :; do e=${ALL[$N]} [ -z "$e" ] && break for i in $(ldd $e | grep '=>' | sed -re 's/.*=> *([^ ]*) .*$/\1/g'); do [[ ${ALL[@]} =~ (^| )$i( |$) ]] && continue ALL+=("$i") # push echo -ne "Found lib dependencies: ${#ALL[@]} ...\r" >&2 done N=$((N+1)) done echo "${ALL[@]}" } findShebang() { local shebang find $VDN_PATH -type f | while read f; do shebang=$(dd if=$f bs=1 count=2 2> /dev/null | tr '\0' '\n' ) reg='#!' [[ "$shebang" =~ $reg ]] && echo $f done } setShebang() { local shebang while read f; do #echo "---" #echo $f shebang=$(cat $f 2> /dev/null | gawk -e '{ print; exit 0 }' | tr '\0' '\n' 2> /dev/null) #echo $shebang new=$(echo "$shebang" | sed -re 's/#! */#!/' | gawk -v SHEBANG=$SHEBANG -e ' /env/ { print SHEBANG" "$2" "$3; exit } { sub(/^.*\//, "", $1); printf SHEBANG" "$1" "$2" "$3 ; exit } ') #echo "new=$new" sed -i -re "1s,.*,$new," $f #sed -i -re '1s,(.*) -u,\1\n\nset -eu,' $f #head -n 3 $f done } findElf() { local elf find $VDN_PATH/slash -type f | while read f; do elf=$(dd if=$f bs=1 count=10 2> /dev/null | tr '\0' '\n' ) reg='ELF' [[ "$elf" =~ $reg ]] && echo $f done } setElf() { while read f; do if ! patchelf --print-interpreter $f &> /dev/null; then continue fi echo "patch $f" patchelf --set-interpreter "/tmp/vdn-slash/lib/x86_64-linux-gnu/ld-2.24.so" $f done } depends() { rm -Rf $SLASH mkdir $SLASH rm -f /tmp/vdn-list-cmd [ -e /tmp/vdn.trace ] && { echo "Read trace" cat /tmp/vdn.trace >> /tmp/vdn-list-cmd } echo "Scan commands" vdn-find-commands >> /tmp/vdn-list-cmd echo "Add manual dependencies" cat << EOF >> /tmp/vdn-list-cmd /bin/bash /bin/ls /bin/sh /bin/dash /usr/bin/less /usr/bin/strace /usr/bin/vim.gtk /usr/bin/ldd /usr/bin/basename /usr/bin/xclock /usr/bin/xauth /lib/x86_64-linux-gnu/libreadline.so.7 /usr/bin/gdk-pixbuf-query-loaders /usr/share/gir-1.0/Gio-2.0.gir /lib64/ld-linux-x86-64.so.2 /usr/bin/python2.7 /usr/bin/python2.7-config /lib/x86_64-linux-gnu/libaudit.so.1 /lib/x86_64-linux-gnu/libpcre.so.3 /lib/x86_64-linux-gnu/libprocps.so.6 /lib/x86_64-linux-gnu/libselinux.so.1 /lib/x86_64-linux-gnu/libtinfo.so.5 /lib/x86_64-linux-gnu/libtinfo.so.5.9 /lib/x86_64-linux-gnu/libnss_dns.so.2 /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.so EOF echo "Find dependencies..." #echo "/bin/bash" > /tmp/vdn-list-cmd #cat /tmp/vdn-list-cmd cat /tmp/vdn-list-cmd | sort -u | { declare -a ALL N=0 while read l; do [[ "$l" =~ ^[[:space:]]*$ ]] && continue [[ "$l" =~ ^[[:space:]]*# ]] && continue ALL+=("$l") # push done N=0 while :; do set +u e=${ALL[$N]} set -u [ -z "$e" ] && { break; } for i in $(ldd $e 2> /dev/null | grep '=>' | sed -re 's/.*=> *([^ ]*) .*$/\1/g'); do [[ ${ALL[@]} =~ (^| )$i( |$) ]] && continue ALL+=("$i") # push #echo -e "Found lib dependencies ${#ALL[@]} : $i ...\r" >&2 done N=$((N+1)) done echo ${ALL[@]} | tr ' ' '\n' | sort -u > /tmp/vdn-list-files } } # main args "$@" [ $REVERSE = 1 ] && { SHEBANG="#!/usr/bin/env" echo "Reverse shebang : $SHEBANG" SHEBANG="#!/usr/bin/env"; findShebang | setShebang $SHEBANG exit } [ $TRACE = 1 ] && { getTrace $@ exit } SHEBANG="#!/tmp/vdn-slash/usr/bin/env" depends echo "Copy..."; cat /tmp/vdn-list-files | copy echo "Patch shebang"; findShebang | setShebang $SHEBANG echo "Patch elf"; findElf | setElf echo "Update pixbuf loader module file" [ ! -d $VDN_PATH/slash/usr/lib/gdk-pixbuf-2.0/2.10.0/ ] && mkdir -p $VDN_PATH/slash/usr/lib/gdk-pixbuf-2.0/2.10.0/ gdk-pixbuf-query-loaders $VDN_PATH/slash/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/* |\ sed -re "s,$VDN_PATH/slash,/tmp/vdn-slash,"> $VDN_PATH/slash/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache #gdk-pixbuf-query-loaders $VDN_PATH/slash/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/* > $VDN_PATH/slash/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders.cache